如何解决ViewPager2中的“违反设计假设”错误?

时间:2019-07-13 07:53:35

标签: android kotlin android-viewpager2

我正在使用ViewPager2,Kotlin和AndroidX。 当适配器不在索引0处并且我更改适配器列表并将当前项设置为索引0时,将引发异常。

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)

ViewPager2的第537行有一个if导致异常:

        // 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.");
        }

这是我更新适配器列表的方式:

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

只有在smoothScroll设置为true时才会发生

我想念什么?

编辑: 我正在使用androidx.viewpager2.widget.ViewPager2

中可用的com.google.android.material:material:1.1.0-alpha08

4 个答案:

答案 0 :(得分:3)

在配置更改时, ViewPager2 遇到了同样的问题。我正在使用:

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

就我而言,我已经覆盖了我的 FragmentStateAdapter 类中的getItemId()方法。当我摆脱了getItemId()方法后,“ IllegalStateException:违反设计假设”的错误不再了! :-)

答案 1 :(得分:3)

我正在使用androidx.viewpager2:viewpager2:1.0.0

对于仍然坚持此原则并需要实施getItemId() containsItem()的人。请检查您的getItemId()containsItem()实现。我的问题是,当我投放10个具有可能性几个项目具有相同值的项目时,会发生此错误。

媒体具有多个具有相同值的数据。

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)

在更新数据甚至只是滑动时,由于使用非唯一ID实现getItemId(),因此viewpager令人困惑。解决方案只是确保您的数据是唯一的或具有自己的ID 。 *我的媒体数据没有ID。

如果打开getItemId()的实现,请注意以下部分:

  • @返回稳定物品ID {@link RecyclerView.Adapter#hasStableIds()}

每个项目都需要有唯一的ID。

答案 2 :(得分:0)

我遇到了同样的问题,但是该错误似乎在当前版本androidx.viewpager2:viewpager2:1.0.0-beta01中(至少对我来说是固定的)。

ViewPager2 1.0.0-beta01 Release Notes

中查看更多

答案 3 :(得分:0)

我的问题是我正在自定义containsItem(),使其具有某些条件,可以在这些条件下从ViewPager删除片段,然后返回false;

旋转电话(然后滑动Design assumption violated)后,我遇到了ViewPager2

我通过返回超类方法return super.containsItem(itemId);

解决了这个问题
@Override
public boolean containsItem(long itemId) {
    // Your code
    return super.containsItem(itemId);
}