【问题标题】:Android Fragment onCreateView triggered when it shouldn't不应该触发的Android Fragment onCreateView
【发布时间】:2015-09-03 18:50:17
【问题描述】:

我有一个活动和几个片段。我的活动有一个抽屉列表,我用它来切换片段,大致如下所示:

public class MainActivity extends AppCompatActivity
{
    private PreferencesFragment preferencesFragment;
    private HomeFragment homeFragment;

    private void selectMenuItem(position)
    {
        Fragment fragment = null;
        switch (position) {
            case 0:
                if (preferencesFragment == null) {
                    preferencesFragment = new PreferencesFragment();
                }
                fragment = preferencesFragment;
            break;
            case 1:
                if (homeFragment == null) {
                    homeFragment = new HomeFragment();
                }
                fragment = homeFragment;
            break;
        }
        getFragmentManager()
            .beginTransaction()
            .replace(R.id.fragment_container, fragment)
            .commit();

    }
}

因此,每当我单击抽屉列表项时,都会以正确的位置调用 selectMenuItem。这会加载现有片段或在需要时创建新片段。问题是,即使片段已经存在,onCreateView 方法也会在片段中触发。我想保持视图的状态,只执行一次 onCreateView 中的代码。文档对 onCreateView 这么说:

当片段第一次绘制其用户界面时,系统会调用它。要为您的 Fragment 绘制 UI,您必须从此方法返回一个 View,它是 Fragment 布局的根。如果片段不提供 UI,则可以返回 null。

那么为什么每次执行 selectMenuItem 时都会调用它?我验证它实际上没有执行新的 Fragment() 块并加载属性值。当我只使用 1 个 Activity 时,如何保持 Fragments 的状态?

savedInstanceState 在 Fragments 的 onCreateViewMethod 中也是 null。在 Fragments 中永远不会触发 onSavedInstanceState。

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    是的,这就是片段生命周期的工作方式。 replace() 删除任何现有的片段,并且删除片段会破坏其视图。在以后的片段事务中重用相同的Fragment 实例将再次从头触发生命周期。

    正如 Ivan 在他的 cmets 中提到的,onSaveInstanceState() 仅在托管活动的 onSaveInstanceState() 被触发时才会被触发,并且仅在活动中替换片段就会使活动保持原样。您可以自己保存状态,参见例如android fragment- How to save states of views in a fragment when another fragment is pushed on top of it

    要让您的片段被垃圾收集,请考虑不要保留对它们的引用。

    【讨论】:

    • 谢谢,这是有道理的。我之前没有保留对它们的引用,只是使用了“New HomeFragment();”每次单击菜单项后。但是,onSaveInstanceState() 从未在我的 Fragments 上调用过。知道为什么吗?
    • onSaveInstanceState() 从布局中删除片段时不会被调用。它仅适用于调用包含活动的onSaveInstanceState() 时。否则,它会保持原样,除非活动被杀死,并且只要您坚持片段引用,您就可以假设成员变量是完整的,只有视图被销毁/重新创建(这当然意味着,不要不要忘记null 成员对onDestroyView() 中的视图的引用(如果有)
    • 我把这个添加到我的片段中:@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Log.v(LOG_TAG, "onSaveInstanceState"); } 但是这从来没有被调用过?我的活动中没有覆盖此方法。
    • 它实际上只在我关闭屏幕时调用。不是在我切换 Fragments 时。
    【解决方案2】:

    如果您用另一个片段替换片段 - 视图被破坏,这是正确的行为。如果您真的需要避免查看视图,您可以使用FragmentTransaction.hide(),但恕我直言,您当前的方法是正确的,您不知道用户是否会想要查看PreferencesFragment,因此没有必要使用不必要的隐藏视图来膨胀内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 2013-02-18
      • 2020-09-25
      相关资源
      最近更新 更多