Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 633 Vote(s) - 3.48 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to fix 'Design assumption violated' error in ViewPager2?

#1
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`
Reply

#2
I had the same problem but the bug seems to be fixed (at least for me) in the current version `androidx.viewpager2:viewpager2:1.0.0-beta01`.

See more in [ViewPager2 1.0.0-beta01 Release Notes][1]



[1]:

[To see links please register here]

Reply

#3
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! :-)
Reply

#4
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.




Reply

#5
My issue was that I was customizing `containsItem()` to have some conditions under which I remove Fragments from the `ViewPager`, and then return `false`;

I encounter `Design assumption violated` after rotating the phone (and then swipe the `ViewPager2`).

I solved that by just returning the super class method: `return super.containsItem(itemId);`

@Override
public boolean containsItem(long itemId) {
// Your code
return super.containsItem(itemId);
}

UPDATE:

> The containsItem method does not have the "CallSuper" annotation and is therefore not required to be called

This is right, no need to call the super; and I didn't call it explicitly before returning a boolean; just returning it solving this issue
Reply

#6
Here is the solution for a straightforward use case

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter

class ViewPager2Adapter(
val dataList: List<Item> = listOf(),
fragmentActivity: FragmentActivity
) :
FragmentStateAdapter(fragmentActivity) {

val pageIds= dataList.map { it.hashCode().toLong() }.toMutableList()

override fun createFragment(position: Int): Fragment {
return MyFragment.newInstance(dataList[position])
}

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

override fun getItemId(position: Int): Long {
return pageIds[position]
}

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

Then I encountered a specific use case when I was replacing my object at the position with a new one then I got the exception.

**Solution:**
Now in case you are making data changes to the adapter i.e. with replacing an object in dataList with a new one, then make sure to replace id in **pageIds** of the old object with the new one.

(viewPager2.adapter as? ViewPager2Adapter)?.apply {
pageIds[oldIndex] = (NewItemObject).hashCode().toLong()
notifyItemChanged(oldIndex)
}
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through