具有两个选项卡的 ViewPager 在滑动和单击时会导致 IndexOutOfBoundsException [英] ViewPager with two tabs causes IndexOutOfBoundsException when sliding and clicking

本文介绍了具有两个选项卡的 ViewPager 在滑动和单击时会导致 IndexOutOfBoundsException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two tabs in which I add two different lists of data, both tabs share a single recyclerview, so at my viewpager adapter, I just create a new instance to populate the data

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,它会抛出一个 IndexOutOfBoundsException,好像往回刷的时候取的是最新的recyclerview数据集

So, the list is displayed correctly, lets say I have two tabs, first tab has 2 items and second tab has 1 item, so, If I click on item 1 at tab 1 I get its id and get the right product, then if I click item 2 on tab 1 it also works, when I swipe to tab 2 and click item 1 it will display correctly again the item, but, if I go back to tab 1 and click item 2 it will throw a IndexOutOfBoundsException, it seems like when swiping back it takes the latest recyclerview data set

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

I dont know how to fix this to prevent creating a different fragment for tab 2 since they show the same data

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

I need to know what is happening, it seems that the last FragmentProducts.newInstance(drinksList) is replacing the whole recyclerview at tab 1

堆栈跟踪

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)

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at java.util.ArrayList.get(ArrayList.java:411) at com.StoreAdapter.getItem(StoreAdapter.kt:45) at com.FragmentProducts.onCartClick(FragmentProducts.kt:65) at com.StoreAdapter$StoreViewHolder$bind$1.onClick(StoreAdapter.kt:59)

StoreAdapter 在这一行出错

StoreAdapter error at this line

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

推荐答案

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

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

If i didn't understand wrong when you came here your viewPagerAdapter already created and you defined your lists as nonNull in adapter( MutableList< Product >).

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

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

For example this block tries to get position 1 when adapter is created and before you set data. It gonna return IndexOutOfBoundsException.

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

Maybe you must try to move this lists in viewPagerAdapter's constructor.

这篇关于具有两个选项卡的 ViewPager 在滑动和单击时会导致 IndexOutOfBoundsException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆