简体   繁体   English

Kotlin 过滤器在 RecyclerView 中搜索 EditText

[英]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:在我的带有 Kotlin 的 android 应用程序 Api 28 中,我创建了一个接口“listOfCountry.xml”,一个用于搜索的 editText 和一个包含所有国家/地区列表的回收器视图,如下代码:

           <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.您正在过滤searchableList列表中的数据,但您已将countries列表应用于适配器。 Change accordingly it will work.相应地改变它会起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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