Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix 'Design assumption violated' error in ViewPager2?

I'm using ViewPager2, Kotlin and AndroidX. When the adapter is not at index 0 and I change the adapter list and set current item to index 0 the exception is thrown.

java.lang.IllegalStateException: Design assumption violated.
        at androidx.viewpager2.widget.ViewPager2.updateCurrentItem(ViewPager2.java:538)
        at androidx.viewpager2.widget.ViewPager2$4.onAnimationsFinished(ViewPager2.java:518)
        at androidx.recyclerview.widget.RecyclerView$ItemAnimator.isRunning(RecyclerView.java:13244)
        at androidx.viewpager2.widget.ViewPager2.onLayout(ViewPager2.java:515)
        at android.view.View.layout(View.java:15596)

In line 537 of ViewPager2 there is an if which causes the exception:

        // Extra checks verifying assumptions
        // TODO: remove after testing
        View snapView1 = mPagerSnapHelper.findSnapView(mLayoutManager);
        View snapView2 = mLayoutManager.findViewByPosition(snapPosition);
        if (snapView1 != snapView2) {
            throw new IllegalStateException("Design assumption violated.");
        }

This is how I'm updating the adapter list:

adapter.list = newList
adapter.notifyDataSetChanged()
viewpager.setCurrentItem(0, true)

It happens only when smoothScroll is set to true

What am I missing?

Edit : I'm using androidx.viewpager2.widget.ViewPager2 available in com.google.android.material:material:1.1.0-alpha08

like image 270
Amir Avatar asked Jul 13 '19 07:07

Amir


2 Answers

I had this same problem with ViewPager2 on configuration change. I'm using:

implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta03'

In my case, I had overridden the getItemId() method in my FragmentStateAdapter class. When I got rid of my getItemId() method, the "IllegalStateException: Design assumption violated" error was no more! :-)

like image 88
ban-geoengineering Avatar answered Nov 12 '22 05:11

ban-geoengineering


I'm using androidx.viewpager2:viewpager2:1.0.0

For whoever still stuck at this, and need to implement getItemId() containsItem(). Please chek your getItemId() and containsItem() implementation. My problem is when I serve 10 item with possibility several item have same value, this error occurs.

Media have several data with same value.

private var mediaId = media.map { it.hashCode().toLong() }

override fun getItemId(position: Int): Long = mediaId[position]

override fun containsItem(itemId: Long): Boolean = mediaId.contains(itemId)

while you updating the data or even simply swiping, the viewpager is confuse because you implement getItemId() with non unique id. The solution is just make sure your data is unique or have their own id. *My media datas dont have id.

If you open the implementation of getItemId() notes this part :

  • @return stable item id {@link RecyclerView.Adapter#hasStableIds()}

you need to have unique id for each of item.

like image 14
Yehezkiel L Avatar answered Nov 12 '22 05:11

Yehezkiel L