【问题标题】:FragmentManager not calling onCreateView with second tab after orientation changeFragmentManager 在方向更改后未使用第二个选项卡调用 onCreateView
【发布时间】:2014-07-04 01:28:21
【问题描述】:

我在 TabA 中有 3 个片段,在 TabB 中有一个 PreferenceFragment。为了重现我启动程序的问题,TabA 显示正常。我单击 TabB,它也显示正常。如果我返回 TabA 并进行方向更改,则下次单击 TabB 时只会出现一个空白屏幕。我已将其缩小到 FragmentManager 不在 TabB 中的 Fragment 上调用 onCreateView。

我正在检查 Fragments 是否不为空,并且不需要重新创建并在方向更改后使用它们的 findFragmentByTag 获取对它们的引用。 TabA 从来没有问题,我尝试用 TabA 重新创建问题,但 onCreateView 总是会被 FragmentManager 为每个 Fragment 调用。我有最低 API 15,目标 19。

MyActivity.java 的精简版可运行

public class MyActivity extends Activity {
    private static final String TAG = "MainActivity";
    public FragmentManager fm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_master);

        fm = getFragmentManager();

        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        ActionBar.Tab tabA = actionBar.newTab().setText("Main");
        ActionBar.Tab tabB = actionBar.newTab().setText("Settings");

        tabA.setTabListener(new TabAListener(this));
        actionBar.addTab(tabA);

        tabB.setTabListener(new TabBListener(this));
        actionBar.addTab(tabB);

        if (savedInstanceState != null) {
            int index = savedInstanceState.getInt("index");
            actionBar.setSelectedNavigationItem(index);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        Log.d(TAG, "onSaveInstanceState");
        super.onSaveInstanceState(outState);
        int i = getActionBar().getSelectedNavigationIndex();
        outState.putInt("index", i);
    }

    public class TabAListener implements ActionBar.TabListener {

        private static final String genTag = "GenerateFragment";
        private static final String aboutTag = "AboutFragment";
        public static final String resultsTag = "ResultsListFragment";

        private ArrayList<Fragment> fragList;

        public TabAListener(Activity activity) {
            fragList = null;
        }

        public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
            // Reselected don't do anything
            Log.d(TAG, "Tab A: on Tab reselected");
        }

        public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
            Log.d(TAG, "Tab A: on Tab Selected");

            // attach all the fragments
            if (fragList == null) {
                fragList = new ArrayList<Fragment>();

                TestFragment genFrag;
                if (fm.findFragmentByTag(genTag) == null) {
                    genFrag = new TestFragment();
                    ft.add(R.id.gen_fragment, genFrag, genTag);
                } else genFrag = (TestFragment) fm.findFragmentByTag(genTag);
                TestFragment aboutFrag;
                if (fm.findFragmentByTag(aboutTag) == null) {
                    aboutFrag = new TestFragment();
                    ft.add(R.id.about_fragment, aboutFrag, aboutTag);
                } else aboutFrag = (TestFragment) fm.findFragmentByTag(aboutTag);
                TestFragment resultsFrag;
                if (fm.findFragmentByTag(resultsTag) == null) {
                    resultsFrag = new TestFragment();
                    ft.add(R.id.results_fragment, resultsFrag, resultsTag);
                } else {
                    resultsFrag = (TestFragment) fm.findFragmentByTag(resultsTag);
                }


                fragList.add(genFrag);
                fragList.add(aboutFrag);
                fragList.add(resultsFrag);
                Log.d(TAG, "Tab A: Added fragments to the ArrayList");

            } else {

                Iterator iter = fragList.iterator();

                while (iter.hasNext()) {
                    Log.d(TAG, "Tab A: Attaching fragments");
                    ft.attach((Fragment) iter.next());
                }
            }
        }

        public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
            Log.d(TAG, "Tab A: on Tab Unselected");

            if (fragList != null) {
                Iterator iter = fragList.iterator();
                while (iter.hasNext()) {
                    Log.d(TAG, "Tab A: Fragments detached");
                    ft.detach((Fragment) iter.next());
                }
            }
        }
    }

    public class TabBListener implements ActionBar.TabListener {

        private static final String settingsTag = "SettingsFragment";

        private ArrayList<Fragment> fragList;

        public TabBListener(Activity activity) {
            fragList = null;
        }

        public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
            // Reselected don't do anything
            Log.d(TAG, "Tab B: on Tab reselected");
        }

        public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {

            Log.d(TAG, "Tab B: on Tab Selected");
            // attach all the fragments
            if (fragList == null) {

                fragList = new ArrayList<Fragment>();
                TestFragment settingsFrag;
                if (fm.findFragmentByTag(settingsTag) == null) {
                    settingsFrag = new TestFragment();
                    ft.add(R.id.frame_main, settingsFrag, settingsTag);
                } else {
                    Log.d(TAG, "Tab B: not null");
                    settingsFrag = (TestFragment) fm.findFragmentByTag(settingsTag);
                }

                fragList.add(settingsFrag);
                Log.d(TAG, "Tab B: Added fragments to the ArrayList");

            } else {

                Iterator iter = fragList.iterator();
                while (iter.hasNext()) {
                    Log.d(TAG, "Tab B: Attaching fragments");
                    ft.attach((Fragment) iter.next());
                }
            }
        }

        public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
            Log.d(TAG, "Tab B: on Tab Unselected");

            if (fragList != null) {
                Iterator iter = fragList.iterator();
                while (iter.hasNext()) {
                    Log.d(TAG, "Tab B: Fragments detached");
                    ft.detach((Fragment) iter.next());
                }
            }
        }
    }

    public static class TestFragment extends Fragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setRetainInstance(true);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            super.onCreateView(inflater, container, savedInstanceState);
            return inflater.inflate(R.layout.fragment_text, container, false);
        }
    }

}

activity_master.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frame_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:orientation="vertical">

            <FrameLayout
                android:id="@+id/gen_fragment"
                android:layout_width="match_parent"
                android:layout_height="0dip"
                android:layout_weight="1" />

            <FrameLayout
                android:id="@+id/about_fragment"
                android:layout_width="match_parent"
                android:layout_height="0dip"
                android:layout_weight="1" />
        </LinearLayout>

        <FrameLayout
            android:id="@+id/results_fragment"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_weight="2" />
    </LinearLayout>
</FrameLayout>

fragment_text.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="test" />
</LinearLayout>

【问题讨论】:

    标签: android android-fragments android-tabs


    【解决方案1】:

    所以,我想我必须删除 MainActivity.onSaveInstanceState 中的超级调用,以便在方向更改后正确调用 TabB 的片段的 onCreateView。嗯,我不确定为什么会这样,所以有人可以解释为什么吗?

    我已经能够收集到 super.onSaveInstanceState 保存活动视图,以供用户导航离开应用程序并最终返回时使用。并且 FragmentManager 还负责通过方向更改来管理 Fragment 的内容。那时我有点迷路了。

    【讨论】:

      猜你喜欢
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多