Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

android - ViewPager with two tabs causes IndexOutOfBoundsException when sliding and clicking

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

From the View

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()

Adapter

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)
            }
        }
    }
}

Then in my 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()
        }

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

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

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

StackTrace

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 error at this line

 fun getItem(position: Int):Product{
        return productList[position]
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
viewPagerAdapter.productsList = productsList
viewPagerAdapter.drinksList = drinksList
viewPagerAdapter.notifyDataSetChanged()

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]
}

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

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...