前言:根据输入框内容过滤出列表中满足要求的数据
方案:通过Filter进行过滤(轻松实现子线程中进行过滤,主线程刷新UI)
1、自定义Adapter实现Filterable接口的getFilter()
class NumberAdapter(context: Context, numberList: List<String>) : RecyclerView.Adapter<NumberAdapter.NumberViewHolder>(),
Filterable{
private val mContext = context
private val mNumberSourceList = numberList//原始数据
private var mNumberFilterList = numberList//筛选后数据
private val mFilter: Filter by lazy {//懒加载方式创建过滤器
object : Filter(){
override fun performFiltering(constraint: CharSequence?): FilterResults {
val filteResults = FilterResults()
//此处进行原始数据过滤
if ( constraint?.isNotEmpty() == true){
val numberListNew = mutableListOf<String>()
for (number in mNumberSourceList){
if (number.contains(constraint)){
numberListNew.add(number)
}
}
filteResults.values = numberListNew
}else{
filteResults.values = mNumberSourceList
}
return filteResults
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
results?.let {
//得到过滤结果刷新UI
mNumberFilterList = it.values as List<String>
notifyDataSetChanged()
}
}
}
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): NumberViewHolder {
val view = LayoutInflater.from(mContext).inflate(R.layout.item_number, p0, false)
return NumberViewHolder(view)
}
override fun onBindViewHolder(p0: NumberViewHolder, p1: Int) {
p0.textView.text = mNumberFilterList[p1]
}
override fun getItemCount(): Int {
return mNumberFilterList.size
}
override fun getFilter(): Filter {
return mFilter
}
class NumberViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
val textView: TextView = itemView.findViewById(R.id.textView)
}
}
2、根据输入内容进行过滤
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val numberList = mutableListOf<String>()
for (i in 1..30){
numberList.add("$i")
}
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerView.layoutManager = layoutManager
val numberAdapter = NumberAdapter(this, numberList)
recyclerView.adapter = numberAdapter
editText.addTextChangedListener(object : TextWatcher{
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
numberAdapter.filter.filter(s)
}
})
}
}
总结:原理仍是通过对数据源进行过滤,然后刷新列表,但通过Filter过滤性能更好,尤其是对海量数据过滤。因为Filter的performFiltering()方法是在子线程中进行的,过滤完成回到主线程的publishResults方法,类似AsyncTask