android – Incorrect RecyclerView item type shown when filtered-ThrowExceptions

Exception or error:

Why is it everytime I filter my RecyclerView an Ad view is shown instead of the result? Is there a way to prevent Ads from appearing in a filtered RecyclerView?

Expected result

enter image description here

Current result

enter image description here

Adapter class

class AdapterMain(
    private val mCtx: Context,
    var myList: MutableList<ItemRV>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), Filterable, PopupMenu.OnMenuItemClickListener {
    private val myListFull = myList.toMutableList()
    private var mClickListener: ItemClickListener? = null

    lateinit var mAdView : AdView

    private val companyFilter = object : Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults {
            val filteredList = ArrayList<ItemRV>()

            if (constraint == null || constraint.isEmpty()) {
                filteredList.addAll(myListFull)
            } else {
                val filterPattern = constraint.toString().toLowerCase().trim { it <= ' ' }

                for (item in myListFull) {
                    if (item.areaName.toLowerCase().contains(filterPattern) || item.areaCode.contains(
                            filterPattern
                        )
                    ) {
                        filteredList.add(item)
                    }
                }
            }

            val results = FilterResults()
            results.values = filteredList
            return results
        }

        override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
            myList.clear()
            myList.addAll(results!!.values as List<MyItem>)
            notifyDataSetChanged()
        }
    }

    override fun getFilter(): Filter {
        return companyFilter
    }

    private val itemRV = 1
    private val itemAD = 2

    override fun getItemViewType(position: Int): Int {
        return if (position % 3 == 0) {
            itemAD
        } else {
            itemRV
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {

        return if (viewType == itemAD) {
            val v = LayoutInflater.from(mCtx).inflate(R.layout.item_ad, parent, false)
            AdViewHolder(v)
        } else {
            val v = LayoutInflater.from(mCtx).inflate(R.layout.item_rv, parent, false)
            AreaViewHolder(v)
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when(holder) {
            is AdViewHolder -> {
                MobileAds.initialize(mCtx) {}
                mAdView = holder.itemView.findViewById(R.id.adView)
                val adRequest = AdRequest.Builder().build()
                mAdView.loadAd(adRequest)
            }

            is AreaViewHolder -> {
            val positionToBind = position - position / 3 - 1

            val product = myList[positionToBind]

            holder.tvTitle.text = product.itemName
            holder.tvSubtitle.text = product.itemDescription
            }
        }
    }

    override fun getItemCount(): Int {
        return myList.size
    }


    inner class AdViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
    .ViewHolder(itemView), View.OnClickListener {
        override fun onClick(v: View?) {
        }
    }

    inner class AreaViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
    .ViewHolder(itemView), View.OnClickListener {
        var tvTitle: TextView = itemView.rvitem_title
        var tvSubtitle: TextView = itemView.rvitem_subtitle
    }

    interface ItemClickListener {
        fun onItemClick(view: View, position: Int)
    }
}

activity layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_rv"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/mRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:scrollbarStyle="outsideInset"/>

</LinearLayout>

ad item ttype

<com.google.android.gms.ads.AdView
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/adView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true"
    ads:adSize="BANNER"
    ads:adUnitId="ca-app-pub-XXXXXXXXXXXXXXXX/XXXXXXXXX">
</com.google.android.gms.ads.AdView>

textview item type

<RelativeLayout
    android:id="@+id/relativelayout_rvitem"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="top"
    android:baselineAligned="false"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:id="@+id/ll_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="100">
        <TextView
            android:id="@+id/rvitem_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            android:layout_weight="95"/>

        <ImageButton
            android:id="@+id/ib_overflow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_more_vertical"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:layout_weight="5"/>
    </LinearLayout>

    <TextView android:id="@+id/rvitem_subtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/ll_title" />
</RelativeLayout>
How to solve:

Your getItemViewType always returns an ad in position 0:

    override fun getItemViewType(position: Int): Int {
        return if (position % 3 == 0) {
            itemAD
        } else {
            itemRV
        }
    }

Consider changing it to not do this in position 0, for example:

return if (position != 0 && position % 3 == 0) {

Leave a Reply

Your email address will not be published. Required fields are marked *