一、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来判断,这些场景后续遇到再考虑设计方案。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐