【问题标题】:ViewPager with two tabs causes IndexOutOfBoundsException when sliding and clicking具有两个选项卡的 ViewPager 在滑动和单击时会导致 IndexOutOfBoundsException
【发布时间】:2020-03-13 01:13:49
【问题描述】:

我有两个选项卡,我在其中添加了两个不同的数据列表,两个选项卡共享一个 recyclerview,所以在我的 viewpager 适配器上,我只需创建一个新实例来填充数据

从视图

val allProducts = completeProductList
     val productsList = mutableListOf<Products>()
                        val drinksList = mutableListOf<Products>()
                        for (product in allProducts) {
                            if (product.isDrink) {
                                drinksList.add(product)
                            } else {
                                productsList.add(product)
                            }
                        }

                        viewPagerAdapter.productsList = productsList
                        viewPagerAdapter.drinksList = drinksList
                        viewPagerAdapter.notifyDataSetChanged()

适配器

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

    var productsList: MutableList<Product> = arrayListOf()
    var drinksList: MutableList<Product> = arrayListOf()

    override fun getItemCount(): Int {
        return 2
    }

    override fun createFragment(position: Int): Fragment {
        return when(position){
            0 -> {
                FragmentProducts.newInstance(productsList)
            }
            else -> {
                FragmentProducts.newInstance(drinksList)
            }
        }
    }
}

然后在我的 FragmentProducts

companion object {
        fun newInstance(product: MutableList<Product>) = FragmentProducts().apply {
            arguments = Bundle().apply {
                putParcelableArrayList(ARG_PROD,ArrayList<Parcelable>(product))
            }
        }
    }

    // I get the product list from the adapter, either drinks or normal products
    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            arguments?.let {
                productsList = it.getParcelableArrayList<Product>(ARG_PROD)
            }
        }

    // Then I just set it up to the shared recyclerview
     override fun onActivityCreated(savedInstanceState: Bundle?) {
            super.onActivityCreated(savedInstanceState)
            adapter.productsList = productsList!!
            adapter.notifyDataSetChanged()
        }

所以,列表显示正确,假设我有两个选项卡,第一个选项卡有 2 个项目,第二个选项卡有 1 个项目,所以,如果我在选项卡 1 上单击项目 1,我会得到它的 id 并获得正确的产品,然后如果我单击选项卡 1 上的项目 2,它也可以工作,当我滑动到选项卡 2 并单击项目 1 时,它将再次正确显示该项目,但是,如果我返回选项卡 1 并单击项目 2,它会抛出一个 @ 987654324@,刷回来的时候好像拿了最新的recyclerview数据集

我不知道如何解决这个问题以防止为选项卡 2 创建不同的片段,因为它们显示相同的数据

我需要知道发生了什么,似乎最后一个 FragmentProducts.newInstance(drinksList) 正在替换选项卡 1 处的整个 recyclerview

堆栈跟踪

java.lang.IndexOutOfBoundsException:索引:1,大小:1 在 java.util.ArrayList.get(ArrayList.java:411) 在 com.StoreAdapter.getItem(StoreAdapter.kt:45) 在 com.FragmentProducts.onCartClick(FragmentProducts.kt:65) 在 com.StoreAdapter$StoreViewHolder$bind$1.onClick(StoreAdapter.kt:59)

StoreAdapter 在这一行出错

 fun getItem(position: Int):Product{
        return productList[position]
    }

【问题讨论】:

  • 请提供完整的堆栈跟踪。
  • @MikeM。提供堆栈跟踪
  • 经过进一步思考,实际上我们可能不需要StoreAdapter,所以如果您的问题空间不足,请暂时发布FragmentProducts

标签: android kotlin android-recyclerview android-viewpager android-architecture-navigation


【解决方案1】:
viewPagerAdapter.productsList = productsList
viewPagerAdapter.drinksList = drinksList
viewPagerAdapter.notifyDataSetChanged()

如果您来到这里时我没有理解错误,您的 viewPagerAdapter 已经创建,并且您在适配器中将列表定义为 nonNull (MutableList)。

fun getItem(position: Int):Product{
    return productList[position]
}

例如,此块尝试在创建适配器时和设置数据之前获取位置 1。它会返回 IndexOutOfBoundsException。

也许您必须尝试在 viewPagerAdapter 的构造函数中移动此列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 2013-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多