Here is my activity and fragment architecture
- MainActivity
- Fragment_A
- Fragment_B
- Fragment_C
- viewPager2
-pageA = ChartFragment.instance("1")
-pageB = ChartFragment.instance("2")
-pageC = ChartFragment.instance("3")
- viewPager2
When I change Fragment to Fragment_C, I will do something for each fragment of viewPager2.
The problem is when I first time go to Fragment_C, viePager2 work corrctly.
But when i change to another fragment and go back to fragment_C. The adapter of viewPager2 would be null.
The function "createFragment" in FragmentStateAdapter only call once.
class FragmentC : Fragment(){
private val pageTitle:List<String> = listOf("PageA", "PageB", "PageC")
private var pageA = ChartPage.newInstance(pageTitle[0], "ppm")
private var pageB = ChartPage.newInstance(pageTitle[1], "%")
private var pageC = ChartPage.newInstance(pageTitle[2], "°C")
private val fragmentList:List<Fragment> = listOf(pageA, pageB, pageC)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
binding = DataBindingUtil.inflate(inflater, R.layout.FragmentC, container, false)
val pagerAdapter = SliderPagerAdapter(this)
pagerAdapter.addFragment(fragmentList)
binding.viewPager2.offscreenPageLimit = 3
binding.viewPager2.adapter = pagerAdapter
TabLayoutMediator(binding.tabLayout, binding.viewPager2){
tab, position ->
tab.text = pageTitle[position]
}.attach()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
pageA.updateChart() //do something, second time go here will crash
pageB.updateChart()
pageC.updateChart()
}
}
class ChartPage : Fragment() {
var mTitle: String? = null
private var mUnit: String? = null
private lateinit var binding: FragmentChartPageBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
mTitle = it.getString(ARG_TITLE)
mUnit = it.getString(ARG_UNIT)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_chart_page, container, false)
binding.chartPageViewModel = viewModel
binding.tvTitle.text = mTitle
binding.tvUnit.text = mUnit
binding.tvValue.text = "_"
Log.i("Shao", "ChartPage onCreateView")
// Inflate the layout for this fragment
return binding.root
}
fun updateChartData(values:ArrayList<Entry>, label:String){
// do something and update the view
}
companion object {
@JvmStatic
fun newInstance(title: String, unit: String) =
ChartPage().apply {
arguments = Bundle().apply {
putString(ARG_TITLE, title)
putString(ARG_UNIT, unit)
}
}
}
}
class SliderPagerAdapter(fragment:Fragment ):FragmentStateAdapter(fragment) {
private var fragmentList:List<Fragment> = listOf()
override fun getItemCount(): Int {
return fragmentList.size
}
override fun createFragment(position: Int): Fragment {
Log.i("Test", "$position")
return fragmentList[position]
}
fun addFragment(fragments: List<Fragment>){
fragmentList = fragments
}
}
Is there only set viewpager2.isSaveFromParentEnabled
to false and re-init each fragment in viewPager2?