10

I'm building an app using ViewPager2 that displays different fragments when swiped. My adapter extends FragmentStateAdapter as described here.

When I put my app into the background and then resume again, the current fragment disappears. What do I need to do to make sure the current fragment is restored correctly?

(Note: I am asking about FragmentStateAdapter, not FragmentPagerAdapter or FragmentStatePagerAdapter.)

Update 1:

My fragment class is as follows:

class PagerFragment : Fragment() {

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val layoutResId: Int = arguments!!.getInt(ARG_LAYOUT_RES_ID)
    return inflater.inflate(layoutResId, container, false)
}

companion object {
    private const val ARG_LAYOUT_RES_ID = "layoutResId"

    fun newInstance(layoutResId: Int): PagerFragment {
        val args = Bundle()
        args.putInt(ARG_LAYOUT_RES_ID, layoutResId)

        val fragment = PagerFragment()
        fragment.arguments = args
        return fragment
    }
}

}

I pass in the desired layout resource id for each fragment when it is created.

My view pager adapter class is as follows:

class ViewPagerAdapter(fm: FragmentManager) : FragmentStateAdapter(fm) 
{
    override fun getItem(position: Int): Fragment {
        return PagerFragment.newInstance(Helper.getLayoutResId(position))
    }

    override fun getItemCount(): Int {
        return Helper.getSize()
    }
}

Adding retainInstance = true does not resolve the problem.

Update 2:

Calling notifyDataSetChanged() in onResume() in my main activity solves the problem for now, although it feels like a heavier hammer than should be necessary. (The original ViewPager + FragmentStatePagerAdapter does not require this type of call to reload fragments properly after bringing in the app from the background.)

Update 3:

Updating my dependency from androidx.viewpager2:viewpager2:1.0.0-alpha01 to the recently released androidx.viewpager2:viewpager2:1.0.0-alpha02 fixes the issue entirely :).

rstockbridge
  • 233
  • 3
  • 11
  • If you share your code it will be more clear. I think its involved with lifecycle of fragment and did you try to use setRetainInstance(true)? – Beyazid Mar 12 '19 at 19:55
  • See updated question :) – rstockbridge Mar 12 '19 at 20:08
  • 3
    There isn't much detail here but one thing I can think of is that if you are dealing with nested Fragments you'd have to pass `childFragmentManager()` rather than `supportFragmentManager()`. – Rodrigo Queiroz Mar 13 '19 at 00:04
  • Thanks for your comment @RodrigoQueiroz. I am not dealing with nested fragments, my `ViewPager2` is the root view of the main activity layout. – rstockbridge Mar 13 '19 at 01:35

1 Answers1

0

Instead of FragmentManager you need to pass your FragmentActivity or Fragment instance as FragmentStateAdapter constructor parameter.

private inner class ViewPagerAdapter(fragment: Fragment) :
    FragmentStateAdapter(fragment) {

     val fragments = arrayOf(
        MyFragment1(),
        MyFragment2()
    )

    override fun createFragment(position: Int): Fragment {
        return fragments[position]
    }

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

Official Documentation: Read Here

Sjd
  • 1,261
  • 1
  • 12
  • 11