android - 保存 ViewPager 中嵌套片段的状态
问题描述
所以我有一个 DrawerLayout 活动。我可以切换到Fragment1
包含 TabLayout 和其他三个片段(NestedFragment1
, NestedFragment2
, NestedFragment3
)。我希望能够在每个 NestedFragments 中保存数据,因为我在其中进行 API 调用。我试图覆盖onSaveInstanceState
并保存数据,但 SavedInstanceState 始终为空。
Fragment1
代码:
class Fragment1 : Fragment() {
private lateinit var viewPager: ViewPager
private lateinit var tabLayout: TabLayout
private lateinit var pagerAdapter: PagerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
pagerAdapter = ForecastPagerAdapter(childFragmentManager)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_forecast, container, false)
viewPager = view.findViewById(R.id.view_pager)
viewPager.offscreenPageLimit = 3
viewPager.adapter = pagerAdapter
tabLayout = view.findViewById(R.id.tabs)
tabLayout.setupWithViewPager(viewPager)
return view
}
}
Example of nested fragment code:
class NestedFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
private lateinit var recyclerViewAdapter: HourForecastAdapter
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
recyclerViewAdapter = HourForecastAdapter()
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater!!.inflate(R.layout.fragment_day_forecast, container, false)
swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_layout_hour)
swipeRefreshLayout.apply {
this.setOnRefreshListener {
performQuery()
}
}
recyclerView = view.findViewById(R.id.recycler_view_hour_forecast)
recyclerView.adapter = recyclerViewAdapter
recyclerView.layoutManager = LinearLayoutManager(activity)
return view
}
fun performQuery() {
// ...
recyclerViewAdapter.forecastList = result.hourly.data
recyclerViewAdapter.notifyDataSetChanged()
}
}
我想保存forecastList
由performQuery
方法返回的(列表)。每次我切换到片段 1 时,嵌套片段中的所有数据都消失了。
这是用于切换片段的代码:
navigationView.setNavigationItemSelectedListener {
var fragment = when (it.itemId) {
R.id.nav_map -> Fragment0()
R.id.nav_forecast -> Fragment1()
R.id.nav_app_info -> Fragment2()
else -> Fragment1()
}
replaceFragment()
it.isChecked = true
drawerLayout.closeDrawers()
true
}
}
编辑:添加片段替换功能:
fun replaceFragment(fragment: android.support.v4.app.Fragment){
val fragmentName = fragment::class.java.simpleName
val isFragmentInBackStack = fragmentManager.popBackStackImmediate(fragmentName, 0)
if (!isFragmentInBackStack) {
fragmentManager.beginTransaction()
.replace(R.id.main_activity_frame, fragment)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.addToBackStack(fragmentName)
.commit()
}
}
解决方案
所以我设法通过使用片段“缓存”来解决这个问题:
fun cacheFragment(fragment: android.support.v4.app.Fragment) {
Log.d("Caching", "Working with ${fragment.javaClass.simpleName}")
var findFragment = supportFragmentManager.findFragmentByTag(fragment.javaClass.simpleName)
if (findFragment == null) {
Log.d("Caching", "Creating new instance of ${fragment.javaClass.simpleName}")
findFragment = fragment.javaClass.newInstance()
}
supportFragmentManager.beginTransaction()
.replace(R.id.main_activity_frame, findFragment, fragment.javaClass.simpleName)
.addToBackStack(null)
.commit()
}
当用户从导航栏中选择一个项目时,我们检查该片段是否已经存在于后堆栈中,然后我们可以重用它。
推荐阅读
- ios - 无法在 Apple 商务管理或 Apple 校园教务管理中选择可用于私人分发给特定组织
- c++ - 有什么方法可以使用 c++ 访问 Github API?
- php - Laravel 枢纽咨询
- php - php 无法读取包含多个文件的 FormData
- python-3.x - 为用户分配角色
- javascript - 悬停时在图表js的条形图中显示列的边框?
- regex - 使用 regex_replace 删除 ansible playbook 中的字符
- python - 保存json列表的最佳格式
- python - 在python中重写一个txt文件,在有某个字符串的地方创建新行
- linux - 无法签出我位于谷歌云下的存储库