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