使用Kuikly开发OpenHarmony项目-路由封装
本文介绍了基于Kuikly框架的简单路由管理封装方案。
一、RouterModule
在Kuikly中,已经提供了RouterModule来实现打开页面和关闭页面。

Kuikly调用Module的方式有三种:https://kuikly.tds.qq.com/DevGuide/module.html#在pager中获取module
在Pager和组合组件中获取Module,主要是在对应的Pager进行操作的;而PagerManager.getCurrentPager()则是在当前显示的Pager进行操作;

二、路由封装
2.1 Kuikly的路由方法比较简单,只能通过pager来操作module来进行打开关闭;但项目的路由跳转和关闭需要灵活一些,例如保证某些Pager是单一的,如果已经存在在路由栈中就需要退出该Pager只上的Pager、再外部关闭路由栈顶的Pager或者,关闭指定的Pager等场景。
2.2 项目中,我们定义了一个RouterManager单例来管理路由,因为外部只能通过Pager来操作RouterModule。我们需要记录已经打开的Pager,添加了addRouter和removeRouter方法,用于记录已经打开的Pager,移除已经退出的Pager。
///全局路由管理
object RouterManager {
//初始化首个Pager的名称
val initRouter = "router"
private val pagerList = mutableListOf<Pager>()
private val pagerNameList = mutableListOf<String>()
///记录isOnlyOne=true的pagerName
private val onlyOnePagerNameList = mutableListOf<String>()
fun addRouter(pager: Pager) {
pagerNameList.add(pager.pageName)
pagerList.add(pager)
if (pager is BasePager && pager.isOnlyOne) {
onlyOnePagerNameList.add(pager.pageName)
}
}
fun removeRouter(pager: Pager) {
for (index in pagerList.size - 1 .. 0) {
if (pagerList[index] == pager) {
pagerList.removeAt(index)
pagerNameList.removeAt(index)
if (pager is BasePager && pager.isOnlyOne) {
onlyOnePagerNameList.remove(pager.pageName)
}
break
}
}
}
}
项目中都需要封装BasePager, 在BasePager中封装一些基础方法和样式的;而在创建Kuikly项目的时候,默认已经创建了BasePager。Pager是有生命周期的:

internal abstract class BasePager : Pager() {
//isOnlyOne=true表示单一pager,如果路由中存在该pager,执行openPage时会将该pager以上的pager关闭掉
open val isOnlyOne = false
override fun created() {
super.created()
isNightMode()
RouterManager.addRouter(this)
}
override fun pageWillDestroy() {
super.pageWillDestroy()
RouterManager.removeRouter(this)
}
}
我们考虑在created中调用RouterManager.addPager方法,记录当前Pager;在pagerWillDestory中调用RouterManager.removePager,移除当前的Pager;这样我们就可以依赖Pager的生命周期方法的回调,在RouterManger中轻松管理维护Pager。
2.3 在RouterManger封装openPager和closePager,用于打开Pager和关闭Pager。
//打开新的页面
//pageName 路由/Pager名称
//params 路由参数
fun openPage(pageName: String, params: JSONObject? = null) {
var foundIndex = -1
//判断是否为单一的Pager
if (onlyOnePagerNameList.contains(pageName)) {
for (index in pagerNameList.indices.reversed()) {
if (pagerNameList[index] == pageName) {
foundIndex = index
break
}
}
}
if (foundIndex != -1) { //已经存在了该Pager,执行退出该Pager之上的Pager
while (foundIndex < pagerList.size - 1) {
val pager = pagerList.removeAt(pagerList.size - 1)
pager.acquireModule<RouterModule>(RouterModule.MODULE_NAME)
.closePage()
}
} else {
pagerList.last().acquireModule<RouterModule>(RouterModule.MODULE_NAME)
.openPage(pageName, pageData = params)
}
}
//关闭当前页面
//pager表示要关闭的pager,如果pager为空,表示关闭当前pager
fun closePage(pager: Pager? = null) {
if (pagerList.size == 1) {
return
}
(pager ?: pagerList.last()).acquireModule<RouterModule>(RouterModule.MODULE_NAME)
.closePage()
}
在RouterManager中用一个onlyOnePagerNameList列表,管理单一Pager的名称,方便在openPager判断是否已经存在该Pager。在BasePager中添加了isOnlyOne属性,用于表示Pager是否为单一Pager,其他Pager继承BasePager后,通过覆盖isOnlyOne属性来控制Pager是否为单一Pager。
在openPage方法中,优先判断单一Pager,是单一Pager就执行关闭该Pager之上的Pager,如果不是,则使用当前显示的Pager打开新的Pager。
在closePage方法中,可以通过传入Pager的方式,关闭该Pager。例如有些需要倒计时后自动关闭页面的场景,就可以通过这种方式进行关闭。
代码已经上传到:https://gitcode.com/saicheng/OHOSGitCodeApp
三、总结
目前项目按照一些常用的场景封装了基本的打开/关闭Pager的操作。但一些大的项目,可能有些场景是Pager是同一个,但根据Pager的参数不一样,显示不同的内容。如果按照现在使用isOnlyOne来控制是否是单一Pager,就无法满足这种场景,需要考虑结合Pager的参数或者定义新的PagerName来判断,这些场景后续遇到再考虑设计方案。
更多推荐


所有评论(0)