Android多回退栈实践(一)_安卓回退栈

Android应用中,我们可以通过点击设备实体返回按键,或者应用左上角标题栏返回按钮进行返回。

点击系统按钮返回
Android多回退栈实践(一)_安卓回退栈_第1张图片
点击应用左上角返回按钮
Android多回退栈实践(一)_安卓回退栈_第2张图片
从用户角度来讲,返回操作是一个类似栈的操作。点击返回时,之前的一系列界面,按照退栈的形式,依次退回。
从开发角度来讲,这样一系列的回退操作,称之为回退栈。

在还未出现Fragment的早期应用,我们一般是不需要关心回退栈的。用户使用如何进入,就如何退出。
在使用Fragment之后,事情开始变得麻烦起来,开发者大多数采用了非常流程的单Activity、多Fragment的UI形式,而随着产品设计的不断迭代,原始的回退策略,已经不能满足我们的要求的,期间存在很长一段时间,我们开发者自己管理回退栈逻辑,在应用层写入自己的Fragment切换逻辑,自己监听回退事件,切换到适当的Fragment。但是这样管理,非常容易出现bug,Fragment的生命周期,也变得混乱起来。这样做也不能完全逃避Android自带的回退栈管理方式,只不过从UI效果上来讲,还能满足需求。

直到2018年5月8日,谷歌正式发布了Navigation,开发者似乎从回退栈中解放了出来,它把FragmentActivity以及Dialog都当做Navigation的一个目的地,通过一种单向图的形式串联起来,使开发者可以在不同的目的地之间进行跳转。开发者不需要关心回退栈的具体细节,我们只需要设定好NavigationGraph即可,当我们需要跳转的时候,我们使用Graph中的某个ActionNavigation会帮我们准备好一切并完成跳转。

一切看起来都是那么完美,但是,如果我们想有多个回退栈呢?

Android多回退栈实践(一)_安卓回退栈_第3张图片

我们现在有这样一个用例,我们的应用首页底部有一个导航栏,这三个按钮可以进入三个不同的分类中,分别是_Music_,FavoriteCollection。我们希望这三个不同的分类中,它们的回退逻辑是单独的:假设从_Music_进入到_MusicDetail_,当我们切换到_Favorite_,然后再切回来的时候,界面显示的是_MusicDetail_。

Android多回退栈实践(一)_安卓回退栈_第4张图片

在官方库androidx.fragment:fragment-ktx:1.4.0-alpha01中,正式支持了多回退栈的特性。
我们来看下,关于多回退栈,官方是如何支持的。

fragment-ktx库中,添加了两个关键的API:

public void saveBackStack(@NonNull String name) 

public void restoreBackStack(@NonNull String name) 

我们先来看saveBackStack的解释:

Save the back stack. While this functions similarly to popBackStack(String, int), it does not throw away the state of any fragments that were added through those transactions. Instead, the back stack that is saved by this method can later be restored with its state in tact.
This function is asynchronous – it enqueues the request to pop, but the action will not be performed until the application returns to its event loop.

参照文档,这个函数的作用有点类似popBackStack函数,但是saveBackStack并不会完全像popBackStack那样(popBackStack会退栈,同时事务里面的状态会丢掉,回退到的Fragment会执行状态恢复),saveBackStack也会执行退栈,但是他会把退栈的这些事务保存起来,用于后面的函数restoreBackStack执行。

简单解释下:

假设现在添加三个Fragment进去:

supportFragmentManager.commit {
    setReorderingAllowed(true)
    replace(R.id.container)
}

supportFragmentManager.commit {
    setReorderingAllowed(true)
    replace(R.id.container)
    addToBackStack("B")
}

supportFragmentManager.commit {
    setReorderingAll

你可能感兴趣的:(android)