0

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")

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?

Shao
  • 11
  • 5

0 Answers0