首页 > 解决方案 > 使用 SearchView 过滤 RecyclerView 结果

问题描述

我正在努力过滤RecyclerView. 这是主要的布局xml

<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
    <variable name="viewmodel" type="TestViewModel"/>
</data>

<androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white">

    <androidx.appcompat.widget.SearchView
            android:id="@+id/search_accounts"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:queryHint="@string/text_hint_filter_accounts"
            android:iconifiedByDefault="true"
            app:layout_constraintTop_toTopOf="@+id/text_account_picker_title"
            app:layout_constraintBottom_toBottomOf="@+id/text_account_picker_title"
            app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"/>

    <androidx.recyclerview.widget.RecyclerView
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:id="@+id/list_accounts"
            android:overScrollMode="never"
            app:layout_constraintTop_toBottomOf="@+id/search_accounts"
            android:layout_marginTop="@dimen/vertical_margin"
            app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layoutAnimation="@anim/layout_animation_fall_down"/>

</androidx.constraintlayout.widget.ConstraintLayout>

适配器类实现Filterable,这里是代码片段getFilter()

override fun getFilter(): Filter {
    return object: Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults {
            constraint?.let {
                val constraintString = constraint.toString()
                searchList = if(constraintString.isEmpty()) accounts
                 else {
                    val filteredList = arrayListOf<AccountDataEntity>()
                    for(account in accounts) {
                        if(account.Name!!.toLowerCase().contains(constraint)) filteredList.add(account)
                    }
                    searchList = filteredList
                    searchList
                }
            }
            val filterResults = FilterResults()
            filterResults.values = searchList
            return filterResults
        }

        override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
            searchList = results?.values as List<AccountDataEntity>
            notifyDataSetChanged()
        }
    }
}

如何绑定搜索查询文本更改以触发适配器上的过滤功能?

我在 xml 上的 SearchView 上尝试了以下操作

app:onQueryTextChange="@{() -> viewmodel.onQueryChange(searchAccounts.getText().toString())}"

但是,构建失败并出现以下错误

****/ 数据绑定错误 ****msg:在 androidx.appcompat.widget.SearchView 上找不到参数类型为 lambda 的属性“app:onQueryTextChange”的设置器。

有人知道你是怎么做到的吗?

标签: androidkotlinsearchviewandroid-databindingandroid-viewmodel

解决方案


在您的 ViewModel 添加

@BindingAdapter("queryTextListener")
public static void setOnQueryTextListener(val searchView: SearchView,val listener:SearchView.OnQueryTextListener) {
    searchView.setOnQueryTextListener(listener)
}

还可以修改 XML,

app:queryTextListener="@{vm.onQueryTextListener}"

推荐阅读