繁体   English   中英

从嵌套片段android中的backstack中删除片段

[英]Remove fragment from backstack in nested fragments android

我有一个 MainActivity,其中添加了一个 Fragment ==> BenefitsFragment 在 BenefintsFragment 中有一个 RelativeLayout

<RelativeLayout
        android:visibility="gone"
        android:background="@android:color/white"
        android:id="@+id/benefitContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent">


    </RelativeLayout>

我正在添加另一个片段,如

   browseBtn.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    RelativeLayout mLayout = (RelativeLayout) view.findViewById(R.id.benefitContainer);
                    mLayout.setVisibility(View.VISIBLE);
                    getChildFragmentManager().beginTransaction()
                            .add(R.id.benefitContainer, new ConfirmPinFragment()).commitNow();
                }
            });

在我的新ConfirmPinFragment我试图回到旧的BenefitsFragment作为

    backBtn.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    getChildFragmentManager().popBackStack();
                }
            });

但是这个popBackStack不起作用,如果我尝试删除使用

        getChildFragmentManager().beginTransaction().remove(ConfirmPinFragment.this).commitNow();

它崩溃说

java.lang.IllegalStateException: FragmentManager is already executing transactions

您需要做两件事才能使其发挥作用。 但首先,确实不需要commitNow() 您需要做的第一件事是在事务期间将要返回的片段添加到后台堆栈中:

browseBtn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            RelativeLayout mLayout = (RelativeLayout) view.findViewById(R.id.benefitContainer);
            mLayout.setVisibility(View.VISIBLE);
            getChildFragmentManager().beginTransaction()
                    .add(R.id.benefitContainer, new ConfirmPinFragment())
                    .addToBackStack("benefits fragment").commit();
        }
    });

当您返回时使用getFragmentManager()而不是getChildFragmentManager()因为您实际上想要保存此片段的片段管理器。 子片段管理器是管理此片段内的片段的管理器。

backBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getFragmentManager().popBackStack();
        }
    });

希望这可以帮助。

使用commitNow()时要小心,您添加的片段不会被添加到 backstack 中。 有关更多信息,请参阅此答案此博客文章

如果你想使用 backstack,你应该使用commit()addToBackStack()而不是commitNow()

commitNow()没有添加到 backstack 的主要原因是 commitNow() 将同步执行事务,如果它会添加到 backstack 中,如果有另一个挂起的异步事务,则事务可能会破坏 backstack 顺序。

您从 FragmentTransaction 添加到后台状态并使用 FragmentManager pop 方法从后台移除:

FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove(myFrag);
trans.commit();
manager.popBackStack();

使用 Kotlin 和 fragment-ktx使用这个:

在你的gradle中:

implementation "androidx.fragment:fragment-ktx:$androidXFragmentKtxVersion"

在你的片段中

childFragmentManager
      .findFragmentByTag(YOUR_TAG)?.let { fragment ->
        childFragmentManager.commit(allowStateLoss = true) {
          remove(fragment)
        }
      }

如果您不使用childFragmentManager,请改用requireActivity().supportFragmentManage r

requireActivity().supportFragmentManage
          .findFragmentByTag(YOUR_TAG)?.let { fragment ->
            requireActivity().supportFragmentManage.commit(allowStateLoss = true) {
              remove(fragment)
            }
      }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM