首页 文章

如何让Fragment自行删除,即它相当于finish()?

提问于
浏览
216

我'm converting an app to use fragments using the compatibility library. Now currently I have a number of activities (A B C D) which chain onto one another, D has a button '确定'当被按下时调用完成然后通过 onActivityResult() 冒泡以额外破坏C和B.

对于我的前Honycomb片段版本,每个活动实际上是片段Af Bf Cf Df的包装器 . 所有活动都是通过 startActivityForResult()onActivityResult() 在每个片段中发起的,可以愉快地调用 getActivity().finish()

我遇到的问题是在我的Honeycomb版本中我只有一个活动A,并且使用 FragmentManager 加载片段Bf,Cf,Df .

我不明白的是,当按下“确定”以删除片段Df,Cf和Bf时,在Df中该怎么办?

我尝试让片段从堆栈中弹出,但这会导致异常 . onActivityResult() 没用,因为我没有使用 startActivityForResult() 加载片段 .

我是否完全以错误的方式思考这个问题?我是否应该实现某种与父片段或活动进行通信的侦听器,以便使用事务管理器进行弹出?

10 回答

  • 35

    我为此创建了简单的方法

    popBackStack(getSupportFragmentManager());
    

    然后将它放在我的ActivityUtils类中

    public static void popBackStack(FragmentManager manager){
            FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
            manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
        }
    

    这很棒,玩得开心!

  • 1

    我不明白的是,当按下“确定”以删除片段Df,Cf和Bf时,在Df中该怎么做?

    步骤#1:让Df告诉D“哟!我们得到了OK点击!”通过调用方法,可以是活动本身,也可以是活动提供的接口实例 .

    步骤#2:让D通过 FragmentManager 删除片段 .

    托管活动(D)是知道活动中的其他片段(与其他活动相比)的活动 . 因此,可能会影响片段混合的片段内事件应传播到活动,这将使适当的编排移动 .

  • -4

    虽然它可能不是最好的方法,但我能想到的最接近的等价物是支持/兼容性库

    getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
    

    要么

    getActivity().getFragmentManager().beginTransaction().remove(this).commit();
    

    除此以外 .

    此外,您可以使用backstack并弹出它 . 但是请记住,片段可能不在backstack上(取决于在那里获得它的片段事务..)或者它可能不是最后一个进入堆栈,因此弹出堆栈可能会删除错误的...

  • 55

    你可以使用下面的方法,它工作正常:

    getActivity().getSupportFragmentManager().popBackStack();
    
  • 256

    你应该让Activity处理添加和删除片段,正如CommonsWare所说,使用一个监听器 . 这是一个例子:

    public class MyActivity extends FragmentActivity implements SuicidalFragmentListener {
    
        // onCreate etc
    
        @Override
        public void onFragmentSuicide(String tag) {
            // Check tag if you do this with more than one fragmen, then:
            getSupportFragmentManager().popBackStack();
        }
    }
    
    public interface SuicidalFragmentListener {
        void onFragmentSuicide(String tag);
    }
    
    public class MyFragment extends Fragment {
    
        // onCreateView etc
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            try {
               suicideListener = (SuicidalFragmentListener) activity;
            } catch (ClassCastException e) {
               throw new RuntimeException(getActivity().getClass().getSimpleName() + " must implement the suicide listener to use this fragment", e);
            }
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            // Attach the close listener to whatever action on the fragment you want
            addSuicideTouchListener();
        }
    
        private void addSuicideTouchListener() {
            getView().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                  suicideListener.onFragmentSuicide(getTag());
                }
            });
        }
    }
    
  • 302

    在Activity / AppCompatActivity中:

    @Override
    public void onBackPressed() {
        if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
            // if you want to handle DrawerLayout
            mDrawerLayout.closeDrawer(GravityCompat.START);
        } else {
            if (getFragmentManager().getBackStackEntryCount() == 0) {
                super.onBackPressed();
            } else {
                getFragmentManager().popBackStack();
            }
        }
    }
    

    然后调用片段:

    getActivity().onBackPressed();
    

    或者在其他答案中说明,请在片段中调用:

    getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
    
  • 3

    查看DialogFragment是否满足您的需求 . DialogFragment有一个dismiss()方法 . 在我看来更清洁 .

  • 17

    在OnCreate:

    //Add comment fragment
                container = FindViewById<FrameLayout>(Resource.Id.frmAttachPicture);
                mPictureFragment = new fmtAttachPicture();
    
                var trans = SupportFragmentManager.BeginTransaction();
                trans.Add(container.Id, mPictureFragment, "fmtPicture");
                trans.Show(mPictureFragment); trans.Commit();
    

    这就是我在点击事件1中隐藏片段的方法

    //Close fragment
        var trans = SupportFragmentManager.BeginTransaction();
        trans.Hide(mPictureFragment);
        trans.AddToBackStack(null);
        trans.Commit();
    

    然后将其显示回事件2

    var trans = SupportFragmentManager.BeginTransaction();
                trans.Show(mPictureFragment); trans.Commit();
    
  • 1

    如果您需要从Backstack历史记录中的第四个片段弹回到第一个片段,请使用标签!

    当你添加第一个片段时,你应该使用这样的东西:

    getFragmentManager.beginTransaction.addToBackStack("A").add(R.id.container, FragmentA).commit()
    

    要么

    getFragmentManager.beginTransaction.addToBackStack("A").replace(R.id.container, FragmentA).commit()
    

    当你想要显示片段B,C和D时,你可以使用:

    getFragmentManager.beginTransaction.addToBackStack("B").replace(R.id.container, FragmentB, "B").commit()
    

    和其他信件....

    要返回 Fragment A,只需调用 popBackStack(0, "A") ,是,使用添加时指定的标志,并注意它必须与命令 addToBackStack() 中的标志相同,而不是命令replace或add中使用的标志 .

    别客气 ;)

  • 4

    为什么不呢:

    getActivity()结束();

相关问题