【问题标题】:SearchView not updating RecyclerView until scrollSearchView 在滚动之前不会更新 RecyclerView
【发布时间】:2021-02-09 15:10:26
【问题描述】:

我正在尝试过滤包含大约 3000 个项目的recyclerList。 我的过滤器有点工作,但由于某种原因它不会更新列表,直到我滚动足够远。

例如:前 2 个元素以字母 A 开头 --> 如果我的过滤器以 B 开头,前 2 个元素仍会显示,直到我滚动到足够远以至于它们不再可见。当我向上滚动时,它们从视图中消失了。

适配器

class LocationAdapter(
    private var locations: ArrayList<Costcenter>,
    private val onLocationClick: (location: Costcenter) -> Unit
) : RecyclerView.Adapter<LocationAdapter.LocationViewHolder>(), Filterable {

    var locationsFiltered = locations

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocationViewHolder {
        val view = LayoutInflater
            .from(parent.context)
            .inflate(R.layout.location_row, parent, false)
        return LocationViewHolder(view)
    }


    override fun getItemCount(): Int = locationsFiltered.size


    override fun onBindViewHolder(holder: LocationViewHolder, position: Int) {
        holder.bind(locationsFiltered[position])
    }


    inner class LocationViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        private val title: TextView = itemView.findViewById(R.id.txtCostCenter)
        private val desc: TextView = itemView.findViewById(R.id.txtCostCenterDescription)

        fun bind(loc: Costcenter) {
            title.text = loc.goederenontvanger
            desc.text = loc.goederenontvanger_omschrijving
            itemView.setOnClickListener {
                onLocationClick.invoke(loc)
            }
        }
    }

    override fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val charSearch = constraint.toString()
                locationsFiltered = if (charSearch.isEmpty()) {
                    locations
                } else {
                    val resultList = ArrayList<Costcenter>()
                    for (row in locations) {
                        if (row.goederenontvanger.toLowerCase()
                                .contains(charSearch.toLowerCase()) || row.goederenontvanger_omschrijving.toLowerCase()
                                .contains(charSearch.toLowerCase())
                        ) {
                            resultList.add(row)
                        }
                    }
                    resultList
                }
                val filterResults = FilterResults()
                filterResults.values = locationsFiltered
                return filterResults
            }

            override fun publishResults(constraint: CharSequence?, results: FilterResults?) {

            }

        }
    }
}

创建 recyclerview 的片段

class LocationsFragment : Fragment() {
    private lateinit var locationAdapter: LocationAdapter
    private val storageViewModel by activityViewModels<StorageViewModel>()
    private lateinit var currentView : View
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        var view = inflater.inflate(R.layout.fragment_locations, container, false)
        var recycler = view.findViewById<RecyclerView>(R.id.recyclerLocations)
        var filter = view.findViewById<SearchView>(R.id.editFilter)
        locationAdapter = LocationAdapter(Utilities.costcenters) { loc -> setSelectedLocation(loc) }
        val recycleMngr: RecyclerView.LayoutManager =
            LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)

        filter.setOnQueryTextListener(object: SearchView.OnQueryTextListener{
            override fun onQueryTextSubmit(query: String?): Boolean {
                return false
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                locationAdapter.filter.filter(newText)
                return false
            }

        })

        recycler.layoutManager = recycleMngr
        recycler.adapter = locationAdapter
        currentView = view
        return view

    }

【问题讨论】:

  • 你在哪里通知适配器你的数据集发生了变化?
  • 调用 notifyDataSetChanged();当你想更新 recyclerview 数据时,在适配器中。

标签: android kotlin android-recyclerview adapter android-adapter


【解决方案1】:

您需要使用publishResults() 发布过滤器时使用过滤结果更新原始列表locationsFiltered,然后notifyDataSetChanged() 以将更改应用于RecyclerView

所以在publishResults() 方法中添加以下内容:

override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
    locationsFiltered =  filterResults.values as ArrayList<Costcenter>
    notifyDataSetChanged()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    相关资源
    最近更新 更多