2

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
    }
}

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Ananiya Jemberu
  • 1,366
  • 1
  • 9
  • 14
  • 1
    It's not understandable what do you try to achieve. onDetach is a callback method of fragments lifecycle. You shouldn't call it by your own. It will be triggered when fragment will be detached. – Eugene Troyanskii May 24 '21 at 14:16
  • If you want to dynamically adding pages, you can modify the data source first, then call `notifyDataSetChanged()` on `ViewPager2`, or check our this: https://stackoverflow.com/questions/61736940/how-to-dynamically-add-and-remove-pages-in-android-viewpager2. – Sam Chen May 24 '21 at 16:33
  • Why do you want to do that manually? and see [this](https://stackoverflow.com/a/36340059/9426046) to get information about fragment lifecycle. – danial iranpour May 31 '21 at 08:23
  • Well the request inside viewPager fragment eg viewmodel won't stop even the parent (viewpager container) fragment detached which occurs some crashes – Ananiya Jemberu May 31 '21 at 13:33

1 Answers1

0

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)

Wilson Tran
  • 4,050
  • 3
  • 22
  • 31