Andoird 传统的布局方式 xml 需要在使用的时候花费额外的时间解析创建 View,直接用 new View 对象又要写很多东西,为了性能直接自定义 View 画?那要敲的代码就更多了。试过 anko,也自己使用 Kotlin DSl 做过类似的布局方式,始终差点味。Flutter Sky 出现的时候似乎出现了曙光,但是新的语言,新的布局方式,而且和原有的项目兼容问题,想说爱你不容易;而且flutter 生成的so 超大文件,加上项目本身的 so 一直是 armv7,armv8a,x86,x86_64 四个平台都有支持 _(:з」∠)_
直到 Jetpack Compose 的出现,直接的基于 Kotlin 构建,不会额外的增加太多的包大小,加上 Flutter 语法的影响,compose 的东西接受起来就变得顺理成章起来。But,compose 从发布到现在这么久了,一直没有出现页面导航的组件,于是就有了这个
[TOC]
先看效果
集成
在 build.gradle
里面加入
dependencies {
//...
implementation 'com.patchself:compose-navigator:0.1.1'
//...
}
如果用的是 gradle.kts, 在 build.gradle.kts
里面加入
dependencies {
//...
implementation("com.patchself:compose-navigator:0.1.1")
//...
}
使用
在你承载 Compose 的 Activity 里加上
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//设置打开的第一个页面
navigationController.initController(SplashPage())
setContent {
// 当然这里也可以先用主题包裹
navigationController.viewContent()
}
}
override fun onBackPressed() {
// 页面跳转回退栈
if (!navigationController.onBackPressed()){
super.onBackPressed()
}
}
}
然后呢就可以写自己的页面了,继承 PageController,然后在里面写页面样式
class CustomPage : PageController() {
override fun getId() = R.id.CustomPage
/**
* 在这个方法里写你的页面内容
* @Composable 这个注解不会被继承需要自己加上去
*/
@Composable
override fun screenContent() {
Scaffold(topBar = {
TopAppBar(
title = { Text(text = "Navigator Sample") },
navigationIcon = {
IconButton(onClick = { navigateBack() }) {
Icon(asset = Icons.Filled.ArrowBack)
}
},
elevation = 4.dp
)
}) {
}
}
}
页面有关生命周期的方法
- 当页面显示在前台显示会调用
onFocus
- 当页面切到后台会调用
onBlur
- 当页面被销毁会调用
destory
PageController
实现了 CoroutineScope
所以可以直接使用协程方法,在 destory 的时候会自动取消所有的协程,不用自己回收
跳转方式
打开新页面
最基础的打开新的页面,使用方式,在继承 PageController 的类里可以这样跳转到一个新的页面
navigateTo(NewPage().also{
pageArgs = args
})
返回上一页
返回上一页也很简单,在页面内,直接调用 navigateBack()
就可以了
回退到特定页面(Clear Top)
回退到指定页面有两种调用方式,带参数和不带参数
resetTo(R.id.HomePage)
//如果需要修改回退目标的属性可以这么用
resetTo<HomePage>(R.id.HomePage){
argsOfHomePage = newValue
}