0

I just implemented my first ever concatAdapter. Since then when I enter some text in the search field, the app crashes when there's no item that matches the search key, if it matches then it returns the result without errors. Before using the concatAdapter there wasn't any issue with it.

This is how I set it up,

        binding.rvHomeItems.layoutManager = LinearLayoutManager(context)
        binding.rvHomeItems.setHasFixedSize(true)
        adapterMyHomeItemList = HomeItemsListAdapter(requireActivity(), itemsList, newView, items)
        adapterBanner = BannerAdapter(requireContext(), offers, remoteImages)
        adapterConcat = ConcatAdapter(adapterBanner, adapterMyHomeItemList)
        binding.rvHomeItems.adapter = concatAdapter

        adapterBanner.notifyDataSetChanged()
        adapterConcat.notifyDataSetChanged()

Following is how I set up the search

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.home_menu, menu)
    super.onCreateOptionsMenu(menu, inflater)

    val item = menu.findItem(R.id.my_search_bar)
    val searchView = item?.actionView as SearchView

    searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {

        override fun onQueryTextSubmit(query: String?): Boolean {
            srchTempItemList.clear()
            if (query != null) {
                if (query.isNotEmpty()) {
                    srchItemList.forEach {
                        if (it.label.toLowerCase(Locale.getDefault()).contains(query)) {
                            srchTempItemList.add(it)
                        }
                        binding.rvHomeItems.adapter?.notifyDataSetChanged()
                    }
                    if (srchTempItemList.size == 0) {
                        showCustomAlertDialog()
                    }
                } else {
                    srchTempItemList.clear()
                    srchTempItemList.addAll(srchItemList)
                    binding.rvHomeItems.adapter?.notifyDataSetChanged()
                }
            }
            return false
        }

        override fun onQueryTextChange(newText: String?): Boolean {

            srchTempItemList.clear()
            val searchText = newText!!.toLowerCase(Locale.getDefault())

            if (searchText.isNotEmpty()) {
                srchItemList.forEach {
                    if (it.label.toLowerCase(Locale.getDefault()).contains(searchText)) {
                        srchTempItemList.add(it)
                    }
                    binding.rvHomeItems.adapter?.notifyDataSetChanged()
                }

                if (srchTempItemList.size == 0) {
                    showCustomAlertDialog()
                }

            } else {
                srchTempItemList.clear()
                srchTempItemList.addAll(srchItemList)
                binding.rvHomeItems.adapter?.notifyDataSetChanged()
            }

            return false

        }
    })
}

Following is the error when the search found matches. The app doesn't crash or throw errors until I scroll down to the end of the list though.

java.lang.IndexOutOfBoundsException: Index: 6, Size: 6
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.abc.xyz.ui.adapters.HomeItemsListAdapter.onBindViewHolder(HomeItemsListAdapter.kt:71)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7178)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7258)
        at androidx.recyclerview.widget.NestedAdapterWrapper.onBindViewHolder(NestedAdapterWrapper.java:157)
        at androidx.recyclerview.widget.ConcatAdapterController.onBindViewHolder(ConcatAdapterController.java:368)
        at androidx.recyclerview.widget.ConcatAdapter.onBindViewHolder(ConcatAdapter.java:188)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7178)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7258)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6125)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6391)
        at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
        at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
        at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
        at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
        at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8633)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

Following is the error when the search doesn't find matches.

    java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.abc.xyz.ui.adapters.HomeItemsListAdapter.onBindViewHolder(HomeItemsListAdapter.kt:71)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7178)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7258)
        at androidx.recyclerview.widget.NestedAdapterWrapper.onBindViewHolder(NestedAdapterWrapper.java:157)
        at androidx.recyclerview.widget.ConcatAdapterController.onBindViewHolder(ConcatAdapterController.java:368)
        at androidx.recyclerview.widget.ConcatAdapter.onBindViewHolder(ConcatAdapter.java:188)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7178)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7258)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6125)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6391)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6231)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6227)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4230)
        at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3630)
        at android.view.View.measure(View.java:27131)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7951)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7951)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7951)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:760)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:833)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7951)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7951)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7951)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7951)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
2021-12-04 01:51:08.641 4793-4793/com.abc.xyz E/AndroidRuntime:     at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7951)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at com.android.internal.policy.DecorView.onMeasure(DecorView.java:1173)
        at android.view.View.measure(View.java:27131)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4187)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2936)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3204)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2618)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9971)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1010)
        at android.view.Choreographer.doCallbacks(Choreographer.java:809)
        at android.view.Choreographer.doFrame(Choreographer.java:744)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:995)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8633)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

Edit:

What I have noticed now is that it doesn't happen only when there is no match found but it also happens, suppose there are 10 items found in the search and when I scroll down to the end of the recyclerview then the app crashes.

Adapter,

    open class HomeItemsListAdapter(
        private val context: Context, private var list: ArrayList<Products>, private val newView: String, private val cartItems: ArrayList<Cart>
    ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    
    private var onClickListener: OnClickListener? = null
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    
            return MyViewHolder(
                ItemHomeListViewLayoutBinding.inflate(
                    LayoutInflater.from(
                        parent.context
                    ), parent, false
                )
            )
        }
    
       @SuppressLint("SetTextI18n")
        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    
            val model = list[position]
    
            if (holder is MyViewHolder) {
    
                if (holder.binding.ivItemImage.visibility == View.INVISIBLE) {
                    holder.binding.ivItemImage.visibility = View.VISIBLE
                }
    
                GlideLoader(context).loadPicture(
                    model.image, holder.binding.ivItemImage
                )
    }
    
        override fun getItemCount(): Int {
            return list.size
        }
    
        fun setOnClickListener(onClickListener: OnClickListener) {
            this.onClickListener = onClickListener
        }
    
        interface OnClickListener {
    
            fun onClick(position: Int, product: Products)
        }
        private class MyViewHolder(val binding: ItemHomeListViewLayoutBinding) : RecyclerView.ViewHolder(binding.root)

}
Codist
  • 737
  • 8
  • 23
  • As the stack trace shows, the crash happens in `HomeItemsListAdapter.onBindViewHolder` so you should show that code. – Tenfour04 Dec 03 '21 at 20:38
  • @Tenfour04 Adapter is added to the question. The error is pointing at `val model = list[position]`. Please note that the error happens only when the searched item is not found, otherwise it returns the result. – Codist Dec 03 '21 at 21:18
  • @Tenfour04 What I have noticed now is that it doesn't happen only when there is no match found but it also happens, suppose there are 10 items found in the search and when I scroll down the `recyclerview` at a certain point (maybe when there is no more item to fill the `recyclerview`) the app crashes. – Codist Dec 04 '21 at 10:15
  • Question is updated with new errors. – Codist Dec 04 '21 at 10:25
  • Now when I commented out all 4 `binding.rvHomeItems.adapter?.notifyDataSetChanged()` inside `searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {` and do a search for an item that's not available, the app didn't crash and called `showCustomAlertDialog()` as in the code. When I do a search for an item that is available, the list is not changed /updated (items in the `recyclerview` remained as is), however, when I scroll do to the end of the `recyclerview` the app crashes like before. – Codist Dec 04 '21 at 12:07
  • NOTE: I can scroll down to the end and go to the last item in the `recyclerview` if I do not initiate a search. – Codist Dec 04 '21 at 12:07
  • The issue is now fixed by replacing `binding.rvHomeItems.adapter?.notifyDataSetChanged()` with `adapterMyHomeItemList.notifyDataSetChanged()` that is inside `searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {` – Codist Dec 04 '21 at 19:10

0 Answers0