Android - 将第一个片段保留在backstack中,并且在替换时不会重新创建实例

时间:2015-06-21 04:47:37

标签: android android-fragments fragmentmanager

我开发了一个包含一些菜单的材质NavigationDrawer。每个菜单都与单个片段相关联。我想让我的FragmentHome()始终在backstack中存活,这样每当我切换到不同的片段并返回时,FragmentHome()应该像以前一样存在。

这是我创建片段的xml,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <include layout="@layout/toolbar" />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <fragment
            android:id="@+id/navigation_drawer"
            android:name="NavigationDrawerFragment"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="start" />
    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

这就是我创建和替换片段的方式,

@Override
    public void onNavigationDrawerItemSelected(int position) {
    Fragment fragment = null;
    String title = getString(R.string.app_name);

        switch (position) {
        case 0:
            fragment = new FragmentHome();
            title = getString(R.string.app_name);

            break;
        case 1:
            fragment = new FragmentCategories();
            title = getString(R.string.title_categories);

        case 2:
            fragment = new FragmentMyPlaylist();
            title = getString(R.string.title_playlist);

        if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.container, fragment);
            fragmentTransaction.commit();

            // set the toolbar title
            getSupportActionBar().setTitle(title);
        }
}

我面临的主要问题是,每当我替换它们时,每个片段都是从头开始创建的。这很烦人,HomeFramgent()的所有组件在创建一次后再次重新创建。

更新

我为这个问题提出了另一个解决方案,即在xml中创建单独的框架并通过主容器替换它们,

首先,我创建了与片段类相关联的单个片段

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <include layout="@layout/toolbar" />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <fragment
            android:id="@+id/FragmentHome"
            android:name="FragmentHome"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <fragment
            android:id="@+id/FragmentCategories"
            android:name="FragmentCategories"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
         <fragment
            android:id="@+id/FragmentMyPlaylist"
            android:name="FragmentMyPlaylist"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <fragment
            android:id="@+id/navigation_drawer"
            android:name="NavigationDrawerFragment"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="start" />
    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

然后我在主要活动中通过id声明每个片段

FragmentManager fm = getSupportFragmentManager();
        fragments[HOME] = fm.findFragmentById(R.id.FragmentHome);
        fragments[CATEGORIES] = fm.findFragmentById(R.id.FragmentCategories);
        fragments[PLAYLIST] = fm.findFragmentById(R.id.FragmentMyPlaylist);
        FragmentTransaction transaction = fm.beginTransaction();

        for (int i = fragments.length - 1; i > 0; i--) {
            transaction.hide(fragments[i]);
        }
        transaction.commit();

现在,当我想要更换一个框架时,我在onNavigationDrawerItemSelected()中执行此操作,

fragmentManager.beginTransaction().replace(R.id.container, new
FragmentHome()).commit();

这解决了重新创建每个片段的问题,并在应用程序运行后创建一次。这再一次给了我一个不刷新其他片段的限制。所有片段都是一次创建的,不会在变化时重新创建,这是我不想要的。

我正在寻找一种有效的方式,以便只有FragmentHome()将保持在后面,并且所有其他片段将在替换时刷新。

非常感谢任何形式的帮助......

1 个答案:

答案 0 :(得分:0)

使用FragmentManager.saveFragmentInstanceState在更换之前捕获HomeFragment的状态。您需要在托管片段的活动中声明一个变量以保存结果。重新选择HomeFragment后,使用Fragment.setInitialSavedState恢复HomeFragment的保存状态,然后再将其添加到FragmentManager中。