简体   繁体   中英

Kotlin filter Search EditText in RecyclerView

In my android app Api 28 with Kotlin, I create an Interface "listOfCountry.xml", an editText for search and a recycler view that contains all the list of country as the following code:

           <EditText
                android:id="@+id/search"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:padding="5dp"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:fontFamily="@font/cairo"
                android:hint="Search..."
                android:imeOptions="actionSearch"
                android:maxLines="1"
                android:singleLine="true"
                android:textSize="14sp"/>

    <TextView
        android:id="@+id/cancelSearch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/cairo"
        android:layout_marginTop="15dp"
        android:layout_marginStart="20dp"
        android:text="@string/cancel_msg"
        android:textSize="14sp" />

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerViewGovernmentOrSectionList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_marginStart="20dp"
    android:layout_marginEnd="20dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/lyt_search" />

I want to get a country from the list with the search filter, the following code is the description of my adapter :

class CountryItemAdapter(var countries: Array<AddressesData>, var mListener: OnItemClickListener) : RecyclerView.Adapter<CountryItemAdapter.ViewHolder>()
        , Filterable {

    private var selectedPos = -1
    var searchableList: MutableList<AddressesData> = arrayListOf()
    private var onNothingFound: (() -> Unit)? = null


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_country, parent, false)
        return ViewHolder(view)
    }
    override fun getItemCount() = countries.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item: AddressesData = countries[position]
        holder.tickImage.visibility = (if (selectedPos == position) View.VISIBLE else View.GONE)
        holder.country.text = item.englishName.toString()

        holder.itemView.setOnClickListener {
            selectedPos = position
            mListener.onItemClick(holder.itemView, item)
            notifyDataSetChanged()
        }

    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val country: TextView = itemView.counrty
        val tickImage: ImageView = itemView.tickGovernment
    }

    interface OnItemClickListener {
        fun onItemClick(view: View, viewModel: AddressesData)
    }
    override fun getFilter(): Filter {
        return object : Filter() {
            private val filterResults = FilterResults()
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                searchableList.clear()
                if (constraint.isNullOrBlank()) {
                    searchableList.addAll(countries)
                } else {
                    val filterPattern = constraint.toString().toLowerCase().trim { it <= ' ' }
                    for (item in 0..countries.size) {
                        if (countries[item].englishName!!.toLowerCase().contains(filterPattern)) {
                            searchableList.add(countries[item])
                        }
                    }}
                    return filterResults.also {
                        it.values = searchableList
                    }
                }

                override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                    if (searchableList.isNullOrEmpty())
                        onNothingFound?.invoke()
                    notifyDataSetChanged()

                }

and I add the following code in my activity :

search.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
            override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
                adapter.filter.filter(charSequence.toString())

            }

            override fun afterTextChanged(editable: Editable) {}
        })

The filter didn't work, I would like to know where's the problem in my code and How can I correct it to make the filter work ?

我认为您在适配器中丢失了getItemCount方法,它必须返回适配器中项目的实际大小。

Its late but may it it will help someone,

You are filtering data in searchableList list but you have applied countries list to adapter. Change accordingly it will work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM