1

Hi guys I am using ViewPager with FragmentStateAdapter. I have an option for the user, in one of the added fragments, to recreate the activity (a method calls: activity.recreate()). However if the activity is recreated I get the following error:

java.lang.IllegalStateException: Design assumption violated.
    at androidx.viewpager2.adapter.FragmentStateAdapter.placeFragmentInViewHolder(FragmentStateAdapter.java:287)
    at androidx.viewpager2.adapter.FragmentStateAdapter.onViewAttachedToWindow(FragmentStateAdapter.java:276)
    at androidx.viewpager2.adapter.FragmentStateAdapter.onViewAttachedToWindow(FragmentStateAdapter.java:67)
    at androidx.recyclerview.widget.RecyclerView.dispatchChildAttached(RecyclerView.java:7556)
    at androidx.recyclerview.widget.RecyclerView$5.addView(RecyclerView.java:860)
    at androidx.recyclerview.widget.ChildHelper.addView(ChildHelper.java:107)
    at androidx.recyclerview.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:8601)

Here is my FragmentStateAdapter:

class MainViewPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {

var fragmentList: ArrayList<Fragment> = arrayListOf()

override fun getItemCount(): Int = fragmentList.size

//Put all the fragments needed based on position
override fun createFragment(position: Int): Fragment {
    return fragmentList[position]
}

fun add(fragment: Fragment) {
    fragmentList.add(fragment)
    notifyDataSetChanged()
}

fun addByPosition(position: Int, fragment: Fragment) {
    fragmentList.add(position, fragment)
    notifyDataSetChanged()
}

fun remove(index: Int) {
    fragmentList.removeAt(index)
    notifyDataSetChanged()
}

override fun getItemId(position: Int): Long {
    return fragmentList[position].hashCode().toLong()
}

override fun containsItem(itemId: Long): Boolean {
    return fragmentList.contains(itemId)
}}

I am using:

implementation "androidx.viewpager2:viewpager2:1.0.0"

and I have tried the followig:

  1. remove getItemId() -> works but I need this method to be overridden in order to retain a proper position of all the elements when add/remove a fragment from the adapter
  2. tried to save the list of fragments inside onSaveInstanceState(outState: Bundle) and pass it back to the adapter but I get the same error.

What am I doing wrong? What is the best way to deal with this error?

user3182266
  • 1,270
  • 4
  • 23
  • 49
  • You should not store fragments. Change your implementation to not using `var fragmentList: ArrayList = arrayListOf()`. – sdex Apr 05 '21 at 09:44
  • @sdex Could you please elaborate more on that ? I am a bit confused why shouldnt I store the fragments in a list? – user3182266 Apr 05 '21 at 09:48
  • There are many reasons. Memory leaks, intervention in normal fragment lifecycle, etc. – sdex Apr 05 '21 at 17:25

0 Answers0