【问题标题】:fragment, add fragment of fragmentTransaction,片段,添加片段事务的片段,
【发布时间】:2017-10-09 06:24:18
【问题描述】:

问题场景:我有三个片段:FragA、FragB、FragC。有一个包含这三个片段的基本活动。所以,现在我不是替换,而是使用片段事务添加片段。顺序如下:从FragA 移动到FragB 到FragC,然后从FragC 回到FragB。 现在,我的疑问是,在从 FragC 回到 FragB 时,没有调用 FragB 生命周期中的任何方法,我什至通过调试 FragB 生命周期中存在的所有方法来验证它。相反,当我们使用fragment事务的replace方法时,会调用fragB的onCreateView()。

如果对问题的理解有任何混淆,请告诉我,如果问题的定义没有很好地框定,请告诉我并道歉。

【问题讨论】:

  • 你能写一些你如何维护片段转换的代码吗?

标签: android android-fragments


【解决方案1】:

替换:这会删除现有的片段并添加一个新的片段,即在您进行交易时它会删除片段 B 并添加片段 C。 此外,当您按下返回按钮时,将创建被替换的片段 B,并调用其 onCreateView。

Fragment的生命周期事件onPause、onResume、onCreateView都会在这里调用。

添加:这会保留现有的片段并添加一个新的片段,即它不会在您进行交易时删除片段 B 并添加片段 C。 这里前一个片段,即片段 B 将处于活动状态,它们不会处于“暂停”状态,因此当按下后退按钮时,不会为 fragB 调用 onCreateView。

这里不会调用Fragment的生命周期事件onPause、onResume、onCreateView。

【讨论】:

  • 您好,感谢您提供的信息丰富的回答。但还有一个疑问:这里之前的片段,即片段 B 将处于活动状态。它到底是什么意思?就像 fragC 覆盖在 fragB 上一样。因此,显然应该调用 frag B 的 onPause。在从 C 到 B 的后退导航中,应调用 B 的 onResume()。对吗?
  • 是的..frag B onPause 没有被调用,它将处于活动状态..按下后 fragC 将弹出,之前的 fragB 将再次可见,并且在 fragB 中不调用任何方法。跨度>
  • 为了更好更清晰的理解,我建议你创建一个包含两个片段的示例应用程序,并尝试所有选项,如添加、替换、addTobackstack 方法。它会让你所有的疑问都清楚。
  • 好的,我将创建一个示例应用程序并执行添加和替换方法的实现。谢谢你的回答
【解决方案2】:

对于fragment的生命周期事件onPause、onResume、onCreateView等生命周期事件,replace会被调用,add不会被调用强>。

【讨论】:

    【解决方案3】:

    如果您添加片段,当片段从片段 C 回到 B 时,页面不会刷新。因此,您放置在片段 B 中的服务不会再次调用。 例如,把一本书放在另一本书上,然后做一个架子。

    如果您REPLACE片段,堆栈中的片段将被覆盖。

    例如:将一本书放在桌子上。桌子上只允许放一本书。所以每次都应该换一本书。

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.add(R.id.container, fragment,back_stack_name); //replace
    transaction.addToBackStack(back_stack_name);//need to add in backstack or not. if not set as null
    fragmentManager.addOnBackStackChangedListener(this);
    transaction.commit();
    

    【讨论】:

    • 嗨,您对我的问题定义的类比非常具有解释性。但是,我的疑问是:在 Android 术语中,如果任何片段覆盖在前一个片段上,那么前一个片段的 onPause() 就会被调用。正确的?如果我错了,请纠正我
    【解决方案4】:

    我正在使用一个 Activity,它使用 3 个 Fragment,其目的是登录和注册,所以每次想要添加一个 Fragment 并获取每个 Fragment 的生命周期,你应该替换当前的 Fragment,依此类推。您可以在 onClick 调用中使用 next 方法并将参数传递给 newInstance Fragment

    private void setFragment(Fragment fr) {
        // create Fragment transaction
        android.support.v4.app.FragmentTransaction fTransaction = getSupportFragmentManager().beginTransaction();
        // Adding to back stack that will allow you use onBackPressed
        fTransaction.addToBackStack(null);
        // Replacing fragment_container which will made lifecycle works 
        fTransaction.replace(R.id.initio, fr, fr.getTag());
        // Commit so inflates the new fragment
        fTransaction.commit();
    }
    

    另外,如果你想使用 onBackPressed 在 Fragment 之间返回,你应该重写下一个方法:

    @Override
    public void onBackPressed() {
        int count = getFragmentManager().getBackStackEntryCount();
    
        if (count == 0) {
            super.onBackPressed();
    
        } else {
            getFragmentManager().popBackStack();
        }
    }´ 
    

    【讨论】:

    • 是的,你是对的。传统上,我应该使用 replace 方法,但意外地遇到了这种情况,这有点令人困惑,因为没有调用片段生命周期中的方法。所以出于好奇,我想知道这个特殊问题的答案。
    【解决方案5】:

    您可以检查片段的可见性。

    覆盖片段中的 setMenuVisibility:

      @Override
      public void setMenuVisibility(boolean menuVisible) {
          super.setMenuVisibility(menuVisible);
          if(menuVisible){
               //fragment is on top and visible
          }
          .....
      }
    

    【讨论】:

      猜你喜欢
      • 2016-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多