在导航组件中包含来自 Backstack 的片段

Unclude fragment from Backstack using Navigation component

我有片段 X、A、B,我正在使用导航架构组件在它们之间导航。

特定于片段 A、B,但片段 X 可以是任何片段(C、D、...);

来自底部导航的片段 A 和 B 及其 "navigations icons" 始终在屏幕上,这意味着用户可以随时从任何片段(包括 A 和 B)转到 A 或 B:


X -> A -> B

X -> B -> A

A -> B -> X

A -> B -> A

//another ways


关于这个案例我的问题:

X -> A -> B -> A -> B -> ?

如果用户从 X 开始,到达 ? 并开始按 "back" 按钮返回,他将抛出 AB 几次:

用户回复:

? -> B -> A -> B -> A -> X

但我想要 "to exclude" 来自 backstack 的片段,如果它们已经在上面的话:

? -> A -> B -> X

如果用户导航:

X -> A -> B -> A

我想看:

A -> B -> X

不是:

A -> B -> A -> X

我正在尝试使用 Pop To 来做到这一点,但它只能 return 我在一个一个的具体片段上。我需要 return 在我启动的 X 片段上,而不是硬编码。包容和单顶不在话下。

我不确定我是否可以使用基本的导航组件来完成它,所以我需要你的建议。如果我做不到,我应该使用什么方式?有什么好的做法吗?


UPD:

我正在使用全局点在 Fragment 之间导航。我的导航是这样的:

右|底链是 X,我可以使用底部导航从其中的任何一个导航到未更改的片段。它是 单个 Activity 应用程序,要导航我只使用:

   //Using global points
   findNavController(R.id.host).navigate(R.id.toLibrary)

在 fragmentTransaction 而不是使用 addToBackStack() 或 add(...) 使用 fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)

以下解决方案采用 片段可见性技术 以便在 onBackPressed().

时管理片段 Backstack

第一步

我们在调用和调用每个 Fragment 时为每个 Fragment 分配一个标签,以便识别 Fragment 中的哪些已添加到 Backstack 并且 前辈。 通过下面的代码,我们将标签分配给将要进行交易的 Fragment

 fragmentManager.beginTransaction()
.replace(R.id.FragmentHolder, Fragment_A OR Fragment_B OR Fragment_ANY, "A or B or ANY")
.addToBackStack(tag).commit();

请记住,您必须为要交易的任何片段指定一个标签

第二个

我们将处理 public void onBackPressed()

必须忽略super.onBackPressed()因为,我们不想默认onBackPressed方法影响按下后退按钮后退栈(按原样)。而且,我们想自己处理Backstack。

给你

@Override
public void onBackPressed() {
    if(isVisible("A")) { //Go some where else you wanna go }
    else if(isVisible("B")){ //Go some where else you wanna go }
    else if(isVisible("X or any"){ //Go some where else you wanna go }
    else { //Go default page }
}


public boolean isVisible(String tag){
    try {
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
        if (fragment != null && fragment.isVisible())
            return true;
        else
            return false;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
 }

按下后退按钮时,我们检查哪个 Fragment 已经可见,并将用户重定向到相应的前任 Fragment

例如:A - > BA -> XX -> B

我正在将此技术用于已发布的应用程序,一切都很好。