【问题标题】:Event when the FragmentTransaction is completedFragmentTransaction 完成时的事件
【发布时间】:2013-11-12 12:26:19
【问题描述】:

FragmentTransaction 完成时是否有可能发生事件?

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment).commit();

事实上,我在我的应用程序中使用了一个 Drawer,我想在事务完成时触发 invalidateOptionsMenu(); 以更改我的操作栏的菜单。

【问题讨论】:

    标签: android listener fragment


    【解决方案1】:

    无需等待分片交易完成,即可调用

    getSupportFragmentManager().executePendingTransactions();
    

    在你的 commit() 函数调用之后。

    这将确保交易完成。

    【讨论】:

    • 我的问题不是我的交易是否顺利,而是要知道它什么时候完成。否则,我的视图的显示和我的操作的菜单栏的更改之间存在差距。
    • 当您调用executePendingTransactions时事务将强制完成。但是,加载视图需要一些时间。要找出这一点,请使用静态函数并从片段的 onResume 调用它。
    • 我认为这是一个有效的答案,即使它本身不是“事件”。 executePendingTransactions() 将阻塞直到事务完成,并且在事务完成时调用它之后的下一个命令,就像事件一样,即使没有事件监听器的开销。跨度>
    • 这是不准确的,当在 commitexecutePendingTransactions 之后添加片段时,片段堆栈具有添加的片段,同时删除或替换一个 Fragment 并且在调用 commitexecutePendingTransactions 之后,删除的 Fragment 仍然在堆栈中,直到稍后的时间。出于用户体验的原因,稍后删除和销毁片段是有道理的,但是这不是获取事务完成事件的正确方法!
    • 我不喜欢这个答案,但我意识到我可以通过在调用 executePendingTransactions() 之后立即使用 EventBus 放置一个事件来使用解决方法,并让我的片段监听该事件,如果它满足删除条件,那么它可以通过在其片段管理器上调用popFragment() 来弹出自己。 (如果它的模型数据不存在,我试图将 popFragment() 代码放入 onResume() 中,但它给出了 IllegalStateException: FragmentManager is already executing transactions 错误。)当它是一个已完成的事务时,我基本上制作了自己的“事件”。
    【解决方案2】:

    嘿!试试这个:

    private OnBackStackChangedListener backStackListener =  new OnBackStackChangedListener() {
    
        @Override
        public void onBackStackChanged() {
            String name = "";
            int position = getSupportFragmentManager().getBackStackEntryCount();
            if(position!=0){
               FragmentManager.BackStackEntry backEntry=getSupportFragmentManager().getBackStackEntryAt(position-1);
               name=backEntry.getName();
    
    
            }
            if(position==0){
                mainActionBar();
            }
            else if(name=="someWord"){
                mainActionBar2();
            }
            else{
                mainActionBar3();
            }
    
        }
    };
     getSupportFragmentManager().addOnBackStackChangedListener(backStackListener);
    

    然后在事务中添加标签到 backStack,如下所示:

    getSupportFragmentManager().beginTransaction()
                    .replace(R.id.main, SomeFragment.newInstance(some argument))
                    .addToBackStack("someWord").commit();
    

    【讨论】:

    • 这仅在您不添加任何自定义动画时有效。
    • onBackStackChanged get 在转换开始时被调用。这是永远无效的。
    • 谢谢@Mikelis,我正在寻找在需要时显示后退按钮,addBackStackChangedListener 起到了魅力:)
    【解决方案3】:

    为时已晚,但这可能会有所帮助(放在这里供某人使用):

    ....
    fragmentTransaction.replace(R.id.contentFrame, fragment);
    fragmentTransaction.runOnCommit(new Runnable() // be carefull on this call. check documentation!!
    {
        @Override
        public void run()
        {
            ... do something...  // this will  run after fragment's on resume. you can check.
        }
    });
    fragmentTransaction.commit();
    

    请检查 runOnCommit() 方法限制!

    【讨论】:

    • 需要 API 26,但并不总是可用。
    • 如果您使用支持 FragmentTransaction 库(大多数应该是),则不需要 API 26。 androidx.fragment.app.FragmentTransaction
    【解决方案4】:
    @Override
    public void onResume() {
        super.onResume();
        getActivity().invalidateOptionsMenu();
    }
    

    FragmentTransaction完成后,会调用Fragment的生命周期方法,如onResume()

    仅供参考,片段可以有自己的菜单, 见http://developer.android.com/reference/android/app/Fragment.html#setHasOptionsMenu(boolean)

    【讨论】:

      【解决方案5】:

      您可以使用this answer 中给出的建议——在事务完成后从onAnimationEnd 方法运行您需要的代码。

      为此,您需要使用例如在 FragmentTransaction 上设置动画

      transaction.setCustomAnimations(R.anim.slide_in_left,
                                      R.anim.slide_out_right);
      

      【讨论】:

        【解决方案6】:

        您可以考虑使用 commitNow() 而不是 commit(),然后您可以确定事务已经完成。 当然,做与不做是交易复杂程度的问题。

        【讨论】:

          【解决方案7】:

          这个方法怎么样:

          FragmentManager fm = ...;
          fm.beginTransaction().add(xxx, FRAGMENT_TAG).commit();
          handler.obtainMessage(FRAGMENT_COMMIT_FINISHED).sendToTarget();
          

          commit()完成后,可以得到FRAGMENT_COMMIT_FINISHED的事件

          【讨论】:

          • 我认为这根本没有帮助,伙计
          • 当你到达下一行时,它还没有提交
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-12
          • 2014-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多