在Android设备的设置app中更改Font Size时,Activity会被重新创建。此时,从Activity访问片段的函数时,requireContext()和requireView()为null,viewModel不会被初始化。
这是我的代码
活动
var pagerAdapter: NewPagerAdapter? = null
fun initView(){
val vpContent = findViewById<ViewPager2>(R.id.vp_content)
val fragmentList = ArrayList<ParentFragment>()
fragmentList.add(FristFragment())
fragmentList.add(SecondFragment())
fragmentList.add(ThirdFragment())
pagerAdapter = NewPagerAdapter(fragmentList, supportFragmentManager, lifecycle)
vpContent.adapter = pagerAdapter
val btnRefresh = findViewById<Button>(R.id.btn_scm_refresh)
btnRefresh.setOnClickListener {
(pagerAdapter)!!.allRefreshPage()
}
}
字符串
适配器
override fun getItemCount(): Int {
return fragmentList.size
}
override fun createFragment(position: Int): Fragment {
return fragmentList[position]
}
fun allRefreshPage(context: Context){
for(i in 0 until fragmentList.size){
fragmentList[i].refreshData()
}
}
型
ParentFragment
abstract class ParentFragment : Fragment() {
abstract fun refreshData()
}
型
ChildFragment
private lateinit var viewModel: NewViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this, ViewModelFactory())[NewViewModel::class.java]
}
override fun refreshData() {
if(context == null || view == null) {
Log.w(TAG, "refreshData: have not context or view")
return
}
viewModel.initAppList(requireContext(), requireView())
}
型
1.为什么会这样?
1.我怎样才能确保null不会出来呢?
1.有没有其他的方法来处理它作为活动中片段的函数?
1条答案
按热度按时间ix0qys7i1#
1/为什么会这样?
PagerAdapter的fragmentList只保存Fragment示例,在需要的时候设置数据,不应该使用fragment变量来更新UI。虽然Fragment被初始化,但它还没有被附加到Activity(用户还没有将tab滚动到该位置)。如果
Fragment
没有被附加,则getContext
或getActivity
始终为null您的
ViewModel
可能没有在正确的位置创建,如Fragment的onCreate文档中所述:请注意,这可以在片段的Activity仍处于创建过程中时调用。
阅读此参考
2/如何确保null不会出现?
正如我所说的,不要使用适配器中的Fragment列表来更新Fragment的数据,这可能会触发UI更新。始终确保任何更新UI和require Context的调用都在onViewCreated之后,您将在
onViewCreated
和onDestroyView
之间获得非空的Context3/是否有任何其他方法将其作为活动中片段的函数?
a/您应该使用
by activityViewModels
委托来创建ViewModel,以避免在错误的位置创建ViewModel,并且activityViewModels
将确保您的ViewModel附加到Activity示例,Activity和Fragment给予相同的ViewModel示例,以便您可以在Activity
和Fragment
之间共享数据字符串
B/将您的数据存储在
ViewModel
内部的LiveData
中,然后从Fragment
观察它。这样,每次重新创建片段时,LiveData
都会再次触发数据以保持View最新。无需每次都调用refreshData
。