Navigation dans l'application Android

Présentation


Avec le développement Android, nous utilisons différentes solutions architecturales (modèles). Par exemple, Mvp , Mvvm , Mvi , etc. ... Chacun de ces modèles résout plusieurs problèmes importants, et comme ils ne sont pas parfaits, ils nous laissent des problèmes non résolus. Par exemple, ces tâches incluent la navigation au sein de l'application (routage), le transfert d'informations d'un écran à un autre (parler de l'écran, je veux dire activité, fragment ou vue), enregistrer l'état de l'application lors du changement de configuration (changement de configuration).


Dans notre entreprise, nous avons également été confrontés à ces problèmes, certains ont été résolus facilement, mais le premier n'a pas trouvé de solution spécifique, après avoir essayé différentes méthodes pour le résoudre, nous avons écrit notre propre bibliothèque Flowzard .


Défi


Dans notre entreprise, nous utilisons l'architecture Mvp . Afin d'avoir une flexibilité maximale lors de l'affichage, la modification et le transfert de données entre les écrans, nous essayons de suivre le principe appelé principe de responsabilité unique . Le principe stipule que chaque module doit résoudre un problème spécifique. Dans notre cas, l'écran doit être isolé de la tâche globale et doit résoudre sa tâche spécifique d'afficher / recevoir des informations. Il ne devrait pas du tout connaître les autres écrans. Nous pouvons donc atteindre une flexibilité maximale. Vous trouverez ci-dessous un exemple de configuration et d'utilisation de la bibliothèque.


Flowzard


Créer un flux


class MainFlow(flowManager: FlowManager) : Flow(flowManager) { //      flow override fun onCreate(savedInstance: DataBunch?, data: DataBunch?) { super.onCreate(savedInstance, data) } } 

Créer un navigateur de flux


Les navigateurs remplissent deux fonctions: créer des conteneurs de flux (activité, fragment, vue) pour les transitions entre flux et des écrans pour les transitions à l'intérieur du flux.


 class DefaultFlowNavigator(activity: AppCompatActivity) : SimpleFlowNavigator(activity){ //    flow  Activity override fun getActivityIntent(id: String, data: Any?): Intent { return when (id) { Flows.SIGN_UP -> Intent(activity, SignupActivity::class.java) else -> throw RuntimeException("Cannot find activity for id=$id") } } } 

Accrocher à l'activité


Pour associer Activity à Flow, nous héritons de FlowActivity et fournissons Navigator, dans notre cas DefaultFlowNavigator.


 class MainActivity : FlowActivity() { override val navigator: Navigator get() = DefaultFlowNavigator(this) } 

Créer FlowManager


 class DefaultFlowManager : FlowManager() { //    (main) flow override fun createMainFlow(): Flow { return MainFlow(this) } //    flow override fun createFlow(id: String): Flow { return when (id) { Flows.SIGN_UP -> SignupFlow(this) else -> throw RuntimeException("Cannot find flow for id=$id") } } } //   FlowManager  Application class App : Application(), FlowManagerProvider { private val flowManager = DefaultFlowManager() override fun getProvideManager(): FlowManager { return flowManager } } 

Messagerie entre le flux et l'écran


Lorsque vous cliquez sur le bouton de connexion, l'activité envoie un message au flux principal. Le flux crée un flux SIGN_UP et attend une réponse de celui-ci. Si la connexion réussit, le flux SIGN_UP envoie le résultat au flux principal et onFlowResult: MainFlow est appelé avec le code et l'objet résultat. Le flux principal vérifie si le résultat est correct, puis renvoie un message à l'activation indiquant que l'utilisateur s'est correctement connecté.


 class MainFlow(flowManager: FlowManager) : Flow(flowManager) { companion object { const val LOGIN_REQUEST_CODE = 1 } //     override fun onMessage(code: String, message: Any) { super.onMessage(code, message) if (code == "main" && message == "login") { newFlow(Flows.SIGN_UP, LOGIN_REQUEST_CODE) } } //       flow override fun onFlowResult(requestCode: Int, result: Result) { super.onFlowResult(requestCode, result) if (requestCode == LOGIN_REQUEST_CODE && result is Result.SUCCESS) { sendMessageFromFlow("main", true) } } } class MainActivity : FlowActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) loginButton.setOnClickListener { //   “login”   “main” flow.sendMessage("main", "login") } //     “main” setMessageListener("main") { if (it is Boolean && it) { statusTextView.text = "Logined" } } } } 

Enregistrement de l'état lors de la modification d'une configuration ou lorsqu'un processus arrête le système d'exploitation


Étant donné qu'Android enregistre les piles d'activités et de fragments, les flux créés avec ces conteneurs enregistrent et restaurent leur état. Avec le conteneur View, vous devrez écrire votre FlowManager personnalisé car la bibliothèque ne dispose pas encore d'un tel gestionnaire. Dans la prochaine mise à jour, il y aura une fonctionnalité pour enregistrer les données intermédiaires du flux.


Comme je ne voulais pas beaucoup de code dans l'article, je me limiterai à cet exemple. Voici un lien vers le référentiel pour une étude détaillée de la bibliothèque.

Source: https://habr.com/ru/post/fr435248/


All Articles