FragmentActivity 和 Fragments:popBackStack

发布于 2024-12-06 23:10:19 字数 1979 浏览 0 评论 0原文

我的 FragmentActivity 在 tabhost 中管理 4 个 listfragments (对于每个 listfragment 我都会跟踪其 backstack )。 ListFragment 共享一个 FrameLayout,它们在其中附加内容。当 onListItemClick 被触发时,每个 ListFragment 让 FragmentActivity 启动一个新的 Fragment,以便当前片段的内容被新片段替换。 如果您调用 A 当前显示的片段(由 ListFragment A 管理)和 B,则在内容 A 与 B 的内容重叠的片段之间切换时,会发生将替换 A 的片段(例如由 ListFragment B 管理),至少 i清除关闭的片段的后台堆栈(示例中的 A)。在片段之间的顺序中,

    if (activeTab != tv) {
        if (activeTab != null) {
            Log.i(TAG, "tag: " + activeTab.getTag() + " detaching...");
            FragmentInfo fragmentInfo = fragments.get(activeTab.getTag());
            //detach the current fragment

            //getSupportFragmentManager().popBackStack((String)activeTab.getTag(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
            ft.detach(fragmentInfo.fragment);
        }

        //get the new 
        FragmentInfo fragmentInfo = fragments.get(tv.getTag());
        Log.i(TAG, "tag: " + tv.getTag() + " fragment: " + fragmentInfo.mClass.getName());
        if (fragmentInfo != null) {
            if (fragmentInfo.fragment == null) {
                fragmentInfo.fragment = Fragment.instantiate(this, fragmentInfo.mClass.getName(), fragmentInfo._args);
                ft.add(R.id.mytabcontent, fragmentInfo.fragment, fragmentInfo._tag);
            } else {
                Log.i(TAG, "attacching fragment: " + fragmentInfo.mClass.getName());
                ft.attach(fragmentInfo.fragment);
            }
        }
    }

当我需要在触发 OnListemItemClick 时更改 listfragment 内容时,我使用

    private void replaceFragment(Fragment fragment, String tag, String backstack) {

    FragmentTransaction ft = manager.beginTransaction();
    ft.replace(R.id.mytabcontent, fragment, tag);
    ft.setTransition(FragmentTransaction.TRANSIT_NONE);
    ft.addToBackStack(backstack);
    ft.commit();
}

您可以帮助我理解为什么吗?提前致谢,并对我的英语不好

编辑表示歉意:我的问题是为什么每次在 ListFragment 之间切换时都需要清除后台堆栈以避免 Fragment 的内容重叠。我做错了什么

My FragmentActivity manages 4 listfragments (for every listfragment I keep trace of its backstack ) within tabhost. The ListFragment shares a FrameLayout in which they attach their content. Every ListFragment when onListItemClick is fired let's the FragmentActivity start a new Fragment so that the content of the current fragment is replaced with the new fragment.
If you call A the fragmetn currently showing (managed by ListFragment A) and B the fragment that would replace A (managed for instance by ListFragment B) happens when switching between fragment that the content A overlaps with the content of B, at least that i clear the backstack of the fragment switched off (A in the example). In order between fragment I do

    if (activeTab != tv) {
        if (activeTab != null) {
            Log.i(TAG, "tag: " + activeTab.getTag() + " detaching...");
            FragmentInfo fragmentInfo = fragments.get(activeTab.getTag());
            //detach the current fragment

            //getSupportFragmentManager().popBackStack((String)activeTab.getTag(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
            ft.detach(fragmentInfo.fragment);
        }

        //get the new 
        FragmentInfo fragmentInfo = fragments.get(tv.getTag());
        Log.i(TAG, "tag: " + tv.getTag() + " fragment: " + fragmentInfo.mClass.getName());
        if (fragmentInfo != null) {
            if (fragmentInfo.fragment == null) {
                fragmentInfo.fragment = Fragment.instantiate(this, fragmentInfo.mClass.getName(), fragmentInfo._args);
                ft.add(R.id.mytabcontent, fragmentInfo.fragment, fragmentInfo._tag);
            } else {
                Log.i(TAG, "attacching fragment: " + fragmentInfo.mClass.getName());
                ft.attach(fragmentInfo.fragment);
            }
        }
    }

while when I need to change the listfragment content when OnListemItemClick is fired I use

    private void replaceFragment(Fragment fragment, String tag, String backstack) {

    FragmentTransaction ft = manager.beginTransaction();
    ft.replace(R.id.mytabcontent, fragment, tag);
    ft.setTransition(FragmentTransaction.TRANSIT_NONE);
    ft.addToBackStack(backstack);
    ft.commit();
}

Could you please help me understand why? Thanks in advance and sorry for my bad english

EDIT: my question is why I need to clear the backstack everytime I switch between ListFragment in order to avoid that content of the Fragment overlaps. What I am making wrong

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼波传意 2024-12-13 23:10:20

好的,所以这个答案假设您希望在每次交换选项卡时擦除每个选项卡的历史记录。我的意思是,选项卡 1 从片段 1 开始,然后单击并将其更改为片段 2。如果选择选项卡 2,您将撤消选项卡 1 的历史记录,下次单击选项卡 1 时,您将返回到frag 1.

话虽如此,解决方案如下:将 onTabUnselected 替换为以下内容

public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            //this segment removes the back history of everything in the tab you are leaving so when you click on the tab again you go back to a fresh start
            FragmentManager man = mActivity.getFragmentManager();
            if(man.getBackStackEntryCount()>0) //this check is required to prevent null point exceptions when clicking off of a tab with no history
                man.popBackStack(man.getBackStackEntryAt(0).getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE); //this pops the stack back to index 0 so you can then detach and then later attach your initial fragment
            //also it should be noted that if you do popbackstackimmediate here instead of just popbackstack you will see a flash as the gui changes back to the first fragment when the code executes
            //end
            ft.detach(mFragment);
        }
    }

Ok, so this answer assumes you want to wipe each tabs back history every time you swap tabs. What I mean by that is Tab 1 starts on frag 1, then you click and change it to frag 2. If you select Tab 2, you will be undoing the history of Tab 1 and next time you click Tab 1 you will be back to frag 1.

With that said here is the solution: Replace your onTabUnselected with the below

public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            //this segment removes the back history of everything in the tab you are leaving so when you click on the tab again you go back to a fresh start
            FragmentManager man = mActivity.getFragmentManager();
            if(man.getBackStackEntryCount()>0) //this check is required to prevent null point exceptions when clicking off of a tab with no history
                man.popBackStack(man.getBackStackEntryAt(0).getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE); //this pops the stack back to index 0 so you can then detach and then later attach your initial fragment
            //also it should be noted that if you do popbackstackimmediate here instead of just popbackstack you will see a flash as the gui changes back to the first fragment when the code executes
            //end
            ft.detach(mFragment);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文