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

时间:2016-12-27 08:35:30

标签: java android android-fragments

我有一个MainActivity,其中我添加了一个片段==> 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

4 个答案:

答案 0 :(得分:1)

使用commitNow()时要小心,您添加的片段不会添加到Backstack中。有关详细信息,请参阅此answerthis blog post

如果您想使用Backstack,则应使用commit()而不是addToBackStack()

commitNow()

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

答案 1 :(得分:1)

您从FragmentTransaction添加到后台状态,并使用FragmentManager pop方法从Backstack中删除:

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

答案 2 :(得分:1)

要完成此任务,您需要做两件事。但首先,确实没有必要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();
        }
    });

希望这有帮助。

答案 3 :(得分:0)

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

在你的gradle中:

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

在你的片段中

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

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

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