列表过滤

前言:根据输入框内容过滤出列表中满足要求的数据

方案:通过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

猜你喜欢

转载自blog.csdn.net/yufumatou/article/details/109384780