首页 > 解决方案 > 如何使用 EditText 为 android 应用程序的回收器视图提供搜索功能?

问题描述

我已经为文件中的搜索选项实现了以下逻辑CustomAdapter.kt

class CustomAdapter(public val context: Context, private val countriesResponse: CountriesResponse) :
RecyclerView.Adapter<CustomAdapter.MyViewHolder>(), Filterable{

var country : ArrayList<String>? = null
var list_country : ArrayList<String>? = null
internal var mFilter : NewFilter

override fun getFilter(): Filter {
    return mFilter
}

init {
    list_country = getCountries()
    country = ArrayList()
    country!!.addAll(list_country!!)
    mFilter = NewFilter(this@CustomAdapter)
}

private fun getCountries(): ArrayList<String>? {
    val list_country = arrayListOf<String>()
    for (list1 in 0..countriesResponse.size)
        list_country.add(list1.toString())
    return list_country
}


class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    var image: ImageView
    var cv_tv_country_name: TextView

    init {
        image = itemView.cv_iv_country_flag
        cv_tv_country_name = itemView.cv_tv_country_name
    }
}


val VIEW_TYPE = 1

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    var itemView = LayoutInflater.from(context).inflate(R.layout.flag_list, parent, false)
    return MyViewHolder(itemView)
}

override fun getItemCount(): Int {
    return list_country!!.size
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    Glide.with(context).load(countriesResponse[position].countryInfo.flag).into(holder.image)
    holder.itemView.setOnClickListener {
        val intent =
            Intent(context, CountryWiseDataActivity::class.java).putExtra("position", position)
        context.startActivity(intent)
    }
    holder.cv_tv_country_name.text = countriesResponse[position].country
}

inner class NewFilter(var customAdapter: CustomAdapter): Filter(){
    override fun performFiltering(constraint: CharSequence?): FilterResults {
        country!!.clear()
        val results = FilterResults()
        if (constraint!!.length == 0){
            country!!.addAll(list_country!!)
        } else {
            val filterPattern = constraint.toString().toLowerCase().trim() { it <= ' '}
            for (list_country in list_country!!) {
                if (list_country.toLowerCase().contains(filterPattern)){
                    country!!.add(list_country) //This line is not getting executed
                }
            }
        }

        results.values = country  // Here I am getting null
        results.count = country!!.size
        return results
    }

    override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
        this.customAdapter.notifyDataSetChanged()
    }

}

现在在Activity我已经实现了TextWatcher。我的代码如下Countries.kt文件。

search_countries.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) {
            countryAdapter.getFilter().filter(s.toString())
            countryAdapter.notifyDataSetChanged()
        }

    })

search_countries是我的LayoutFile.

我正在从 an 中获取国家/地区,列表RESTAPI中共有215国家/地区。我已经完成了必要的实现,我想知道为什么我的搜索功能不起作用?

标签: androidandroid-studiokotlin

解决方案


据我所知,您的代码正在执行此操作:

  • 在 init 块中,list_country设置为国家索引列表,从 0 到 [ countryResponse.size](这应该是国家名称吗?)
  • country也是国家索引的列表 - 它被初始化为与相同的完整列表list_countries
  • 过滤器代码清除country,然后用与list_country搜索词匹配的所有元素填充它
  • list_country虽然包含一堆索引,“0”...“214”所以除非你输入数字,否则没有任何匹配
  • country最终为空(不应该为空?)

我认为如果你重命名listCountries为类似allCountryIndicescountriestofilteredCountryIndices或类似的东西会有所帮助,所以很清楚它们是什么。您想对 的内容运行所有过滤countriesResponse,对吗?


同样在onBindViewHolder(列表项计算出它需要显示的数据)中,您正在获取一个列表position并将其用作索引countriesResponse- 当您的列表包含所有国家/地区时,这很好,因此每个位置都与中的一个项目匹配countriesResponse,但是当您过滤你的列表你只会有几个项目,并且位置 0 的项目可能不会是项目 0 in countriesResponse,你知道吗?

如果country是您的过滤countryResponse索引列表,您想要country[position]获取正确的 ID。也getItemCount应该使用country.size- 那是您正在显示的实际列表,可能是所有国家/地区,也可能是一些国家/地区(如果已过滤)。listCountry只是所有索引的参考(你真的不需要吗?)


顺便说一句,如果你 makecountrylistCountry非 null (你永远不需要在你的代码中将它们设置为 null )你会为自己省去很多麻烦,并且不需要把它们放在!!任何地方!喜欢:

var country : ArrayList<String>
var list_country : ArrayList<String>

您将它们分配在init块中,这样就可以了。(实际上它们可能是val因为你分配它们一次,但我不想让事情过于复杂!它确实让你在 Kotlin 中的生活更轻松)


推荐阅读