从后台堆栈的第三个片段转到第一个片段:Android

11

我有一个事件序列,通过这个序列我依次将三个片段添加到后退栈中。这些片段中的每一个都覆盖了活动的整个屏幕。

我已经存储了从Frag1提交返回的is。

现在在Frag3中,基于具体的点击,我想直接返回到Frag1并且弹出/删除中间的所有片段。

因此,当点击按钮时,我发送一条消息给活动执行以下操作:

getSupportFragmentManager().popBackStack(mFrag1Id, FragmentManager.POP_BACK_STACK_INCLUSIVE);

但我只看到了一个空白屏幕,所以我认为没有加载任何片段。

我甚至尝试过: 在提交中 - fragmentTransaction.addToBackStack("Fragment1"); 然后

getSupportFragmentManager().popBackStack("Fragment1", FragmentManager.POP_BACK_STACK_INCLUSIVE);

但它不起作用。 能有人帮我吗?

谢谢。


3
我猜你需要调用 popBackStack() 两次。尝试调试,Fragments 真的很糟糕 :) - agamov
我同意,但是有人可能对此有一些意见? - Sunny
1
@agamov,你能帮我吗! - offset
@offset 没问题,欢迎! - agamov
5个回答

12

好的,我找到了问题。

FragmentManager.POP_BACK_STACK_INCLUSIVE 会弹出所有片段,包括传递作为参数的片段的 id。

因此,例如:

getSupportFragmentManager().popBackStack(mFrag1Id, FragmentManager.POP_BACK_STACK_INCLUSIVE);

在这里,它将弹出栈中的所有内容,包括其id为mFrag1Id的片段。


我该如何获取Fragment的ID?我是这样添加Fragment的:val fragmentTransaction = supportFragmentManager.beginTransaction() fragmentTransaction.add(id, fragment, tag) fragmentTransaction.addToBackStack(null) fragmentTransaction.commit() - Vikas Pandey

8
当您打开片段A并导航到片段B,然后再到片段C,然后您想关闭片段C和B并着陆在片段A上时,
现在,在某些情况下,您想关闭片段C和片段B,并希望着陆在片段A上...然后使用FragmentManager的这个逻辑来执行此任务。
1.首先获取后退堆栈中片段条目的数量(当我们将任何片段添加到addToBackStack(“Frag1”)时,片段后退堆栈条目将增加)。
FragmentManager fmManager = activity.getSupportFragmentManager();
Log.e("Total Back stack Entry: ", fmManager.getBackStackEntryCount() + "");

现在假设您想关闭当前的片段(片段C)和上一个片段(片段B),那么简单的逻辑是获取BackStackEntryCount-2,此时您的返回堆栈条目计数将为3(片段A,片段B和片段C)

这里的-2是因为我们想要后退2个片段步骤(片段C和片段B)

所以只需要两行代码:

if (fmManager.getBackStackEntryCount() > 0) {
fmManager.popBackStack(fmManager.getBackStackEntryAt(fmManager.getBackStackEntryCount()-2).getId(), FragmentMaanger.POP_BACK_STACK_INCLUSIVE);
}

您也可以通过添加两次“popBackStack()”来实现此操作,但这不是一个好的方式。
FragmentManager fmManager = activity.getSupportFragmentManager();
fmManager.popBackStack();
fmManager.popBackStack();

7

从第三个片段中,您应该调用popBackStack();两次(一次用于删除第三个片段,另一次用于删除第二个片段)。

android.support.v4.app.FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.remove(ThirdFragment.this);
transaction.commit();
fm.popBackStack();
fm.popBackStack();

0
如果您想让用户返回到起始片段,下面的代码片段将对您有所帮助。
public static void popBackStackInclusive(AppCompatActivity activity) {

    FragmentManager fragmentManager = activity.getSupportFragmentManager();

    for (int i = 1; i < fragmentManager.getBackStackEntryCount(); i++){
        try {
            int fragmentId = fragmentManager.getBackStackEntryAt(i).getId();
            fragmentManager.popBackStack(fragmentId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        } catch (Exception e) {
            Timber.d("Fragment Back Stack Error: %s", e.getLocalizedMessage());
        }
    }

}

如果想防止用户在没有后退栈的情况下关闭应用程序,请看下面。

@Override
public void onBackPressed() {
    FragmentManager fragmentManager = getSupportFragmentManager();

    if(fragmentManager.getBackStackEntryCount() > 1) {
        super.onBackPressed();
    } else {
        // TODO: Show dialog if user wants to exit app or;
        //finish();
    }
}

0

当用户进入[1] > [2] > [3]

然后在onBackPress中,用户将会回到[3] > [1]

在你不想在backPress中显示的fragment中添加。无论你有多少个fragments,你都可以在任意两个fragments之间弹出任何一个fragment

[第二个] fragment内执行以下2个步骤:你想要popUp/close

步骤1. 在调用[3] fragment之前,只需在fragmentTransaction之前添加fragmentManager.popBackStack();即可。 (在此行之后,它会销毁/弹出第2个fragment并再次打开第1个fragment,然后再打开第3个fragment。这意味着当用户在第3个fragment上按下返回按钮时,在最近的fragment中,有第1个fragment而不是第2个)
步骤2. 也要使用fragmentTransaction添加.addToBackStack(null)

enter image description here

[2] 片段:在此,当按钮被点击时,我们将打开第三个片段

{ //.....
        //this code inside [2]nd fragment. onBackPress at [3] we want to close[2] between [3]>[1]

        //on button click listener
        view.findViewById(R.id.btnOpen3ndFrag).setOnClickListener(v -> {

            if (getActivity() != null) {
                FragmentManager fragmentManager = getActivity().getSupportFragmentManager();

                //this  .popBackStack will close this [2]nd fragment. before open 3rd fragment
                fragmentManager.popBackStack(); //<<<Step1: add this before fragmentTransaction

                //here we will open 3rd fragment
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, new ThirdFragment(), "FirstFragment")
                        .addToBackStack(null) //<<Step2: add this also.
                        .commit();
            } else {
                Toast.makeText(getActivity(), "Something went wrong", Toast.LENGTH_SHORT).show();
            }
        });

        //....
    }

(^_^) 开心编程


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接