简体   繁体   English

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

[英]Remove fragment from backstack in nested fragments android

I have a MainActivity in which I have Added a Fragment ==> BenefitsFragment in BenefintsFragment there is a RelativeLayout我有一个 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>

I am adding another fragment like我正在添加另一个片段,如

   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();
                }
            });

In my new ConfirmPinFragment I am trying to go back to old BenefitsFragment as在我的新ConfirmPinFragment我试图回到旧的BenefitsFragment作为

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

However this popBackStack not working, if i try to remove using但是这个popBackStack不起作用,如果我尝试删除使用

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

It crashes saying它崩溃说

java.lang.IllegalStateException: FragmentManager is already executing transactions

There are two things you need to do for this to work.您需要做两件事才能使其发挥作用。 But first of all there is really no need for commitNow() .但首先,确实不需要commitNow() The first thing you need to do is to add the fragment you want to go back to into the back stack during the transaction:您需要做的第一件事是在事务期间将要返回的片段添加到后台堆栈中:

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();
        }
    });

and when you go back use the getFragmentManager() instead of getChildFragmentManager() because you actually want the fragment manager that holds this fragment.当您返回时使用getFragmentManager()而不是getChildFragmentManager()因为您实际上想要保存此片段的片段管理器。 Child fragment manager is the manager that manages the fragments inside this fragment.子片段管理器是管理此片段内的片段的管理器。

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

Hope this helps.希望这可以帮助。

Be careful when using commitNow() , the fragment that you add won't be added into backstack.使用commitNow()时要小心,您添加的片段不会被添加到 backstack 中。 See this answer and this blog post for more info.有关更多信息,请参阅此答案此博客文章

If you want to use backstack you should use commit() with addToBackStack() instead of commitNow()如果你想使用 backstack,你应该使用commit()addToBackStack()而不是commitNow()

The main reason why commitNow() is not adding into backstack is commitNow() will execute the transaction synchronously, if it'll added into backstack the transaction can broke the backstack order if there are another pending asynchronous transactions. commitNow()没有添加到 backstack 的主要原因是 commitNow() 将同步执行事务,如果它会添加到 backstack 中,如果有另一个挂起的异步事务,则事务可能会破坏 backstack 顺序。

You add to the back state from the FragmentTransaction and remove from the backstack using FragmentManager pop methods:您从 FragmentTransaction 添加到后台状态并使用 FragmentManager pop 方法从后台移除:

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

Using Kotlin and fragment-ktx using this one:使用 Kotlin 和 fragment-ktx使用这个:

In your gradle:在你的gradle中:

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

In your Fragment在你的片段中

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

If you are not using childFragmentManager use requireActivity().supportFragmentManage r instead如果您不使用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