【发布时间】:2018-04-13 15:38:12
【问题描述】:
所以我目前的实现如下。基本上我会预加载所有片段,将它们设置为当前Activity 的字段,然后添加或显示片段是否已添加。
mFeedTopicsFragment = FeedTopicsFragment.getInstance();
mUserDiscussionsFragment = UserDiscussionsFragment.getInstance(SessionPersistor.getSignedInUserId());
mUserConversationsFragment = MyConversationsFragment.getInstance(SessionPersistor.getSignedInUserId());
activityMainNavigation.setOnNavigationItemSelectedListener((MenuItem item) -> {
switch (item.getItemId()) {
case R.id.menu_item_go_to_feed_fragment:
if (getSupportFragmentManager().findFragmentByTag(FeedTopicsFragment.class.getSimpleName()) != null) {
getSupportFragmentManager()
.beginTransaction()
.show(mFeedTopicsFragment)
.hide(mUserDiscussionsFragment)
.hide(mUserConversationsFragment)
.commit();
} else {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.activity_main_container_fragment, mFeedTopicsFragment, FeedTopicsFragment.class.getSimpleName())
.hide(mUserDiscussionsFragment)
.hide(mUserConversationsFragment)
.commit();
}
return true;
case R.id.menu_item_go_to_user_discussions_fragment:
if (getSupportFragmentManager().findFragmentByTag(UserDiscussionsFragment.class.getSimpleName()) != null) {
getSupportFragmentManager()
.beginTransaction()
.show(mUserDiscussionsFragment)
.hide(mFeedTopicsFragment)
.hide(mUserConversationsFragment)
.commit();
} else {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.activity_main_container_fragment, mUserDiscussionsFragment, UserDiscussionsFragment.class.getSimpleName())
.hide(mFeedTopicsFragment)
.hide(mUserConversationsFragment)
.commit();
}
return true;
case R.id.menu_item_go_to_user_conversations_fragment:
if (getSupportFragmentManager().findFragmentByTag(MyConversationsFragment.class.getSimpleName()) != null) {
getSupportFragmentManager()
.beginTransaction()
.show(mUserConversationsFragment)
.hide(mFeedTopicsFragment)
.hide(mUserDiscussionsFragment)
.commit();
} else {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.activity_main_container_fragment, mUserConversationsFragment, MyConversationsFragment.class.getSimpleName())
.hide(mFeedTopicsFragment)
.hide(mUserDiscussionsFragment)
.commit();
}
return true;
但是,我觉得这是一种不好的方法,因为我通过预加载片段来浪费内存。但是,我不想调用replace 每个FragmentTransaction,因为每次我在片段之间导航时都会调用onCreateView 并强制执行新的API 调用。我不想要这个,只要我留在这个Activity,假设我从FeedTopicsFragment开始,向下滚动到RecyclerView中的第10个项目,从FeedTopicsFragment导航到UserDiscussionsFragment,向下滚动到RecyclerView中的第三项,再回到FeedTopicsFragment,我还是会看到第10项,再回到UserDiscussionsFragment,我会看到第三项。
我正在考虑使用onSaveInstanceState 保存数据的Bundle 并将Bundle 加载到onActivityCreated 中。但恐怕onSaveInstanceState 可能不会被调用,onActivityCreated 也不会。 那么在不创建 Fragment 实例或将其保存为字段并在我离开 Activity 后删除该状态的情况下保存状态的最佳解决方案是什么?
当前每个片段都有一个loadData 方法,该方法在该方法内部调用API 并使用响应数据设置RecyclerView、TextView 等字段。一旦我在 Activity 中执行 SwipeRefresh,它将在每个片段上调用 loadData。
我也不确定如何执行此刷新部分,基本上我必须获取所有片段的实例,然后在每个片段上调用 loadData。但一次只有一个片段在activity_main_container_fragment 中。在这种情况下,我认为保存每个片段的实例是有意义的,这样我就可以在这些本地实例上调用 loadData。
【问题讨论】:
-
有多种方法旨在避免每次将 Fragment 附加到 Activity 时都进行 API 调用:保留 Fragments、Loader/LoaderManager(需要习惯,但可以很好地将加载从展示)和最后(到目前为止):LiveData 等。我认为学习如何在应用中使用它们是值得的。
-
什么是保留片段?只是在 FragmentManager 中按标签保存片段?
-
不,一点也不。如果 configuration change 发生,保留的 Fragment 不会被销毁。通常它没有(不应该)有任何视图
-
还是不明白retained Fragments。你有一些我可以查看的资源的链接吗?
-
只需点击“配置更改”(你不可能在 5 秒内读完所有内容)
标签: android android-fragments android-recyclerview navigation