在运行时构建的Fragment上始终为null savedInstanceState(导航视图)

时间:2016-03-01 00:32:17

标签: android android-fragments bundle

我尝试使用一个Activity和与导航项一样多的片段构建NavigationView: 第一项窃听 - >第一个片段加载随机远程图像; 第二/第三项轻拍 - >其他片段被加载。 我的目标是,在切换回第一项时,显示已下载的图像,而不是获取新图片。

activity_main.xml中

<android.support.v4.widget.DrawerLayout
(.....)
android:id="@+id/drawer_layout">

<!-- This LinearLayout represents the contents of the screen  -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- The ActionBar displayed at the top -->
    <include
        layout="@layout/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <!-- The main content view where fragments are loaded -->
    <FrameLayout
        (......)
        android:id="@+id/flContent"/>
</LinearLayout>

<!-- The navigation drawer that comes from the left -->
<android.support.design.widget.NavigationView
    (.......)
    android:id="@+id/nvView" />

MainActivity

public class MainActivity extends AppCompatActivity {

Fragment homeFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //......
    setupDrawerContent(nvDrawer);
    if (findViewById(R.id.flContent) != null && savedInstanceState == null) {
       homeFragment = new HomeFragment();
       getSupportFragmentManager().beginTransaction().add(R.id.flContent, homeFragment, "homeFragment").commit();
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, "homeFragment", homeFragment);
}

private  void setupDrawerContent(NavigationView navigationView) {
    navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    selectDrawerItem(menuItem);
                    return true;
                }
            }
    );
}

public void selectDrawerItem(MenuItem menuItem) {
    // Create a new fragment and specify the item to show based on
    // position
    Fragment fragment = null;

    Class fragmentClass = null;
    switch(menuItem.getItemId()) {
        case R.id.nav_first_fragment:
            fragmentClass = HomeFragment.class;
            break;
        case R.id.nav_second_fragment:
            fragmentClass = SecondFragment.class;
            break;
        default:
            fragmentClass = HomeFragment.class;
    }
    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }

    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();

    // Highlight the selected item, update the title, and close the drawer
    menuItem.setChecked(true);
    setTitle(menuItem.getTitle());
    mDrawer.closeDrawers();
   }
}

HomeFragment

    public class HomeFragment extends Fragment {


    private static final String TAG = "HomeFragment";

    public HomeFragment() {
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        // ......
        View fragmentView = inflater.inflate(R.layout.home_fragment, container, false);
        if (savedInstanceState == null) {
            // FETCH RANDOM IMAGE
        }else {
            // RESTORE IT (but always null)
        }
        return fragmentView;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putSerializable(/*SOME DATA*/);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState != null) {
            // ALWAYS NULL
        }
    }
 }

我找到this回答但我不知道如何做,因为我只是引用了FrameLayout。

跟踪生命周期方法我注意到MainActivity处于活动状态,因此它从不调用onSaveInstanceState,我也不知道如何在HomeFragment中使用Bundle来恢复onCreateView中的savedInstanceState。 你有什么提示可以分享吗? 非常感谢

1 个答案:

答案 0 :(得分:0)

当你用另一个片段替换片段时,前一个片段(被替换的片段)将被销毁,并且其非静态成员变量中的任何数据都将丢失。

如果要保留片段的图像,可以使用位图缓存来存储图像,但只有在为片段加载相同图像时才能使用。如果您正在加载随机图像并希望在下次实例化同一个片段时加载相同的图像(因此您希望Home片段始终加载它在第一次实例化时加载的相同图像),那么您需要保留数据。有几种方法可以做到这一点,您可以在Home片段中使用静态变量来保存图像的URL,您可以将其存储在SharedPreferences中,您可以将其传递给Activity,然后活动会将其传递回它再次创建时的主片段,依此类推。选择最适合您需求的解决方案。