`onDetach` not working inside viewpager2 fragment

Viewed 301

I was wondering if it was possible to detach view pager 2 fragment manually, because I wasn't able to call onDetach which result some crashes (since it can run on the background) on viewPagers fragment.

//ViewPagerPage1.kt
override fun onDetach(){
   super.onDetach()
   Log.d("TAG", "VP fragment Detached")//doesn't show up

I tried things like:

//Main.kt
override fun onDetach(){
   super.onDetach()
    //Parent fragement where viewPager implement
    viewPager.removeAllViews()//no luck
}

or scoped inside Coroutine:

//Main.kt
val job = CoroutineScope(Main).launch {
   view.apply {
            val listOfFragment = arrayListOf<Fragment>(
                ...
            )
            val adapter = TabsPagerAdapter(
                listOfFragment,
                requireActivity().supportFragmentManager,
                requireActivity(),
                lifecycle

            )
            adapter

            viewPager1.adapter = adapter
            val tabNames = listOf<String>(
               ...
            )
            TabLayoutMediator(tabLayout, viewPager) { tab, p ->
                viewPager.setCurrentItem(tab.position, true)
                tab.text = tabNames[p]

            }.attach()
        }

}
//Main.kt
override fun onDetach(){
  super.onDetach()
  job.cancel()
}

yet these things doesn't work I also tried adding log to both fragment (view pager parent and child)

//ViewPagerPage1.kt
override fun onDetach(){
   super.onDetach()
   Log.d("TAG", "VP fragment Detached")
}
//Main.kt
override fun onDetach(){
   super.onDetach()
   Log.d("TAG", "fragment Detached")
}

as result when back is pressed TAG: fragment Detached only show up Note Main.kt is the fragment which contains ViewPagerPage1

incase if you want the adapter:

class TabsPagerAdapter(val array: ArrayList<Fragment>,
                       val manager: FragmentManager,
                       val context: Context,
                       val lifecycle: Lifecycle): FragmentStateAdapter(manager, lifecycle){
    override fun createFragment(position: Int): Fragment {
        return array[position]
    }

    override fun getItemCount(): Int {
        return array.size
    }
}

1 Answers

View pager can't detach cause memory leak. To avoid this, change the code to create the instance of TabsPagerAdapter according to the following code

val adapter = TabsPagerAdapter(
            listOfFragment,
            childFragmentManager, 
            requireActivity(),
            viewLifecycleOwner.lifecycle)

Note:

  • requestActivity().supportFragmentManager -> childFragmentManger : All its children should be managed by itself instead of activity.

  • lifecycle -> viewLifecycleOwner.lifecycle : The fragment has 2 lifecycles, one for the view (viewLifecycleOwner.lifecycle), one for itself (lifecycle). In this case, the adapter is the view so we just need to use the lifecycle for the view (viewLifecycleOwner.lifecycle)

Related