【问题标题】:How to avoid Fragment recreation?如何避免 Fragment 消遣?
【发布时间】:2017-10-31 08:49:14
【问题描述】:

我有 2 个Fragments F1F2。我使用以下代码从Activity 打开第一个Fragment F1

MyFragment f1 = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString("GameLevelType", "Learn");
dialog.setArguments(bundle);
FragmentTransaction gameTransaction = getSupportFragmentManager().beginTransaction();
gameTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
gameTransaction.add(android.R.id.content, f1).addToBackStack(null).commit();

然后从Fragment F1 我正在使用以下代码打开另一个Fragment F2

MySecondFragment f2 = new MySecondFragment();
            Bundle bundle = new Bundle();
            FragmentTransaction transaction = ((AppCompatActivity) context).getSupportFragmentManager().beginTransaction();
            bundle.putInt("CurrentPosition", getAdapterPosition());
            bundle.putIntArray("x", kolamTracingGameList.get(getAdapterPosition()).getX());
            bundle.putIntArray("y", kolamTracingGameList.get(getAdapterPosition()).getY());
            bundle.putInt("Level", (getAdapterPosition() + 1));
            bundle.putString("GameType", "Kolam");
            fragment.setArguments(bundle);
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            transaction.replace(android.R.id.content, f2).addToBackStack(null).commit();

问题是当我关闭Fragment F2 并且Fragment F1 进入前台时。整个 F1 正在重新创建(再次调用onViewCreated())。我不希望 F1 在前台重新创建。

【问题讨论】:

  • 我们会的,这就是它的工作方式。如果您有一些在 onViewCreated 中运行的代码,请尝试移动它。
  • 你错了。 onViewCreated() 并不意味着正在重新创建片段。它只是意味着正在重新创建片段的视图。如果要在创建片段时运行代码,请将其放入onCreated()

标签: android android-fragments


【解决方案1】:

对于第二个片段,使用添加而不是替换。

replace- 移除已有的fragment并添加一个新的fragment。在fragment F2中按下返回按钮时,会再次调用oncreateView中的fragment。

add - 保留现有片段并添加一个新片段,这意味着现有片段将处于活动状态,它们不会处于“暂停”状态。当在片段 F2 中按下后退按钮时,片段 F1 的方法均无效再次调用。

transaction.add(android.R.id.content, f2).addToBackStack(null).commit();

【讨论】:

    【解决方案2】:

    如果你想让 Fragment 保持它的状态并且不通过onCreateView 你不能替换它。我们来看看 Fragment 的生命周期:

    当您在片段上调用替换时,您基本上是在告诉容器删除所有存在的片段,并添加一个新片段。如果你删除一个片段,onPause() 将一直被调用,直到onViewDestroyed(),这意味着如果你取回片段实例并将其添加到容器中,它没有视图,所以onCreateView() 将被调用。

    如果您在 Fragment2 上调用 add,它将是 Visible Fragment,但 Fragment1 仍将在容器中。现在,一旦您删除 Fragment2(backPress 或以编程方式),Fragment1 将变为可见,而无需调用 onCreateView() 或任何其他状态。

    代码:

    替换这个:

    transaction.replace(android.R.id.content, f2).addToBackStack(null).commit();
    

    与:

    transaction.add(android.R.id.content, f2).addToBackStack(null).commit();
    

    【讨论】:

      【解决方案3】:

      每次在执行FragmentTransaction 之前,您都会创建一个新的FragmentF1F2。你有几个选择:

      1. 在创建时保留对F1/F2 的全局引用。因此,只有当他们是 null 时,您才创建一个新的。
      2. 或者,如果您不想保留全局引用,请为F1/F2 分配一个唯一标记。这样您就可以调用FragmentManager.findFragmentByTag(),如果它仍然存在,它将返回给您Fragment。然后您进行交易。

      选项 2 的示例:

      FragmentManager supportFragmentManager = getSupportFragmentManager();
      MyFragment f1 = supportFragmentManager.findFragmentByTag("f1_fragment");
      
      if (f1 != null) f1 = new MyFragment();
      
      FragmentTransaction gameTransaction = supportFragmentManager.beginTransaction();
             gameTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
      gameTransaction.replace(android.R.id.content, f1, "f1_fragment")
          .commit();
      

      【讨论】:

      • 您能否提供一个示例以及第二个选项的一些代码。 @Ahmadulhoq
      • @Hiren 我已经添加了示例,请检查编辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 2011-03-30
      相关资源
      最近更新 更多