在Android应用程序中导航

引言


在Android开发中,我们使用了不同的架构解决方案(模式)。 例如, MvpMvvmMvi等。。。每种模式都解决了几个重要问题,并且由于它们不是完美的,所以给我们留下了一些未解决的问题。 例如,这些任务包括在应用程序内导航(路由),在屏幕之间传输信息(说屏幕,我是指“活动”,“片段”或“视图”),更改配置时保存应用程序的状态(配置更改)。


在我们公司中,我们也面临这些问题,有些问题很容易解决,但是第一个没有找到特定的解决方案,尝试了各种解决方法,我们编写了自己的Flowzard库。


挑战赛


在我们公司中,我们使用Mvp架构。 为了在屏幕之间显示,更改和传输数据时具有最大的灵活性,我们尝试遵循称为“ 单一责任原则”的原则 。 该原则指出,每个模块都必须解决特定的问题。 在我们的情况下,屏幕应与全局任务隔离开,并应解决其显示/接收信息的特定任务。 他根本不应该了解其他屏幕。 这样我们就可以实现最大的灵活性。 以下是设置和使用库的示例。


流箭


创建流程


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

创建流导航器


导航器执行两个功能:创建用于在流之间进行转换的流容器(活动,片段,视图),以及用于在流内部进行转换的屏幕。


 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") } } } 

捕捉活动


为了将Activity与Flow关联起来,我们继承了FlowActivity并提供了Navigator(在我们的示例中为DefaultFlowNavigator)。


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

创建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 } } 

流程和屏幕之间的消息传递


当您单击登录按钮时,活动将消息发送到主流。 流创建一个SIGN_UP流,并等待它的响应。 如果登录成功,则SIGN_UP流将结果发送到主流,并且onFlowResult:使用代码和结果对象调用MainFlow。 主流程检查结果是否正确,然后将消息发送回用户已成功登录的激活。


 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" } } } } 

更改配置或进程停止操作系统时保存状态


由于Android保存了Activity和Fragment堆栈,因此使用这些容器创建的流将保存并恢复其状态。 使用View容器,您将需要编写自定义FlowManager,因为该库还没有这样的管理器。 在下一个更新中,将提供一种功能,用于保存流中的中间数据。


由于我在文章中不需要很多代码,因此我将限于此示例。 这是到资源库的链接 ,用于详细研究库。

Source: https://habr.com/ru/post/zh-CN435248/


All Articles