如何使用 Kotlin 在 ListAdapter 中使用 Filterable?

2024-05-08

我会用一个SearchView过滤我的RecyclerView,在 stackoverflow 和其他网站上我发现只是使用的示例Filterable与 Java 和RecyclerView.Adapter当我使用时ListAdapter..

所以我试图自己制作自定义过滤器,但是当我尝试过滤适配器时,我只是得到一个空值MutableList in publishResults.

My Adapter代码如下所示:

class ArticoliListAdapter : ListAdapter<Articolo, ArticoliListAdapter.ArticoliViewHolder>(ArticoliComparator()), Filterable {
    private val list = mutableListOf<Articolo>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticoliViewHolder {
        return ArticoliViewHolder.create(parent)
    }

    override fun onBindViewHolder(holder: ArticoliViewHolder, position: Int) {
        val current = getItem(position)
        holder.bind(current)
    }

    override fun getItemId(position: Int): Long {
        val articolo = currentList[position]
        return articolo.barcode.hashCode().toLong()
    }




    class ArticoliViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val barcode: TextView = itemView.findViewById(R.id.barcode)
        private val qta: TextView = itemView.findViewById(R.id.qta)
        private val desc: TextView = itemView.findViewById(R.id.desc)
        private val um: TextView = itemView.findViewById(R.id.um)
        fun bind(articolo: Articolo?) {
            barcode.text = articolo?.barcode
            qta.text = articolo?.qta?.formatForQta()
            um.text = articolo?.um?.toLowerCase(Locale.ITALIAN)
            desc.text = if(articolo?.desc.isNullOrEmpty()) "-" else articolo?.desc
        }

        private fun Float.formatForQta(): String {
            val floatString = this.toString()
            val decimalString: String = floatString.substring(floatString.indexOf('.') + 1, floatString.length)
            return when (decimalString.toInt() == 0) {
                true -> this.toInt().toString()
                false -> "%.3f".format(this)
            }
        }

        companion object {
            fun create(parent: ViewGroup): ArticoliViewHolder {
                val view: View = LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_layout, parent, false)
                return ArticoliViewHolder(view)
            }
        }
    }

    class ArticoliComparator : DiffUtil.ItemCallback<Articolo>() {
        override fun areItemsTheSame(oldItem: Articolo, newItem: Articolo): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(oldItem: Articolo, newItem: Articolo): Boolean {
            return oldItem.qta == newItem.qta
        }
    }

    override fun getFilter(): Filter {
        return customFilter
    }

    private val customFilter = object: Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults {
            val filteredList = mutableListOf<Articolo>()
            if (constraint == null || constraint.isEmpty()){
                filteredList.addAll(currentList)
            }else {
                val filterPattern = constraint.toString().toLowerCase(Locale.ITALIAN).trim { it <= ' ' }
                for (item in currentList) {
                    if (item.barcode.toLowerCase(Locale.ITALIAN).contains(filterPattern) || item.desc?.toLowerCase(
                            Locale.ITALIAN
                        )!!.contains(filterPattern)) {
                        filteredList.add(item)
                    }
                }
            }
            val results = FilterResults()
            results.values = filteredList
            return results
        }

        override fun publishResults(constraint: CharSequence?, filterResults: FilterResults?) {
            list.clear()
            list.addAll(filterResults?.values as MutableList<Articolo>)
            notifyDataSetChanged()
        }

    }

}

所以我想知道哪种方法是构建自定义过滤器以在 Kotlin 中使用 ListAdapter 来过滤 recyclerView 中的数据的正确方法。

我在片段中调用过滤器,如下所示:

    override fun onQueryTextChange(query: String?): Boolean {
        adapter.filter.filter(query)
        return false
    }

但是当我尝试过滤时什么也没发生,并且仍然显示所有项目......

数据至RecyclerView适配器是从我设置的ViewHolder数据是从数据库中获取的(LiveData<List<Articolo>>)

这是我的片段中的代码:

   articoliViewModel.articoli.observe(viewLifecycleOwner) { articoli ->
        articoli.let { adapter.submitList(it) }
    }

我在下面列出的代码中几乎没有缺陷。

  1. currentList正在保存列表中的当前项目,而不是完整的项目列表。即,如果您有 10 个项目,过滤后您会得到 3 个项目,那么currentList将持有 3 件物品而不是 10 件。所以你不能使用currentList用于过滤列表。相反,你坚持CompleteList并对这个应用过滤器。

  2. 你不应该打电话notifyDataSetChanged()这完全违背了拥有的全部目的DiffUtils,而不是你打电话#submitList

  3. Al 认为您有一个对完整列表作为全局变量的引用,但您从未为其赋值,它始终为空。

我制作了一个工作示例来说明。请尝试在您的代码中添加以下基本代码。我的使用类型为String只是为了使示例易于理解,您可以使用自定义对象。您还可以修改代码以使其看起来更好,但我认为它足以了解如何ListAdapter works.

class ArticoliListAdapter : ListAdapter<String, ArticoliListAdapter.ArticoliViewHolder>(ArticoliComparator()), Filterable {
    private var list = mutableListOf<String>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticoliViewHolder {
        return ArticoliViewHolder.create(parent)
    }

    override fun onBindViewHolder(holder: ArticoliViewHolder, position: Int) {
        val current = getItem(position)
        holder.bind(current)
    }

    fun setData(list: MutableList<String>?){
        this.list = list!!
        submitList(list)
    }

    class ArticoliViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val desc: TextView = itemView.findViewById(R.id.txtName)
        fun bind(name: String) {
            desc.text = name.toUpperCase()
        }

        companion object {
            fun create(parent: ViewGroup): ArticoliViewHolder {
                val view: View = LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_list, parent, false)
                return ArticoliViewHolder(view)
            }
        }
    }

    class ArticoliComparator : DiffUtil.ItemCallback<String>() {
        override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
            return oldItem == newItem
        }
    }

    override fun getFilter(): Filter {
        return customFilter
    }

    private val customFilter = object : Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults {
            val filteredList = mutableListOf<String>()
            if (constraint == null || constraint.isEmpty()) {
                filteredList.addAll(list)
            } else {
                for (item in list) {
                    if (item.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
                        filteredList.add(item)
                    }
                }
            }
            val results = FilterResults()
            results.values = filteredList
            return results
        }

        override fun publishResults(constraint: CharSequence?, filterResults: FilterResults?) {
            submitList(filterResults?.values as MutableList<String>)
        }

    }
}

当您将数据设置为适配器时,您会调用setData not submitList.

articoliViewModel.articoli.observe(viewLifecycleOwner) { articoli ->
    articoli.let { adapter.setData(it) }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Kotlin 在 ListAdapter 中使用 Filterable? 的相关文章

随机推荐

  • 将 SQLite 的 FTS3/4 与 Python 3 结合使用

    我一直在使用 python 的 Flask 框架开发 peewee 的示例博客应用程序 看https github com coleifer peewee https github com coleifer peewee 内部示例 gt 博
  • Zxing库无法解析

    我正在使用 zxing 库开发应用程序 我导入了zxing项目到我的工作场所 当我导入时遇到了一些问题 通过编译项目java 1 7 我做到了 CameraConfigurationUtils失踪 我从library source Reso
  • Fitnesse Slim:如何连接符号

    如何将符号与两侧的文本连接起来 例如 Prefix GAR 多变的 todayDate Suffix 1 GAR todayDate 1 这将评估为 GAR 07202012 1 在 Fitnesse 中运行测试时 似乎串联正在起作用 GA
  • 停止 Erlang 守护进程

    除了跑步 killall 9 beam smp 当我知道 Erlang 节点的情况时 如何以编程方式杀死它 sname 如果我不希望心跳监视器重新启动该进程 如何确保上述问题的任何答案也会终止心跳 有没有一个不错的指南来将 Erlang 部
  • DataGrid、TextBox - 绑定和即时更新

    我的应用程序 包含图中的窗口 DataGrid 的 ItemsSource 设置为 editList 声明为 IList editList 数据网格设置为只读 供应商名称文本框的绑定设置为 Text Binding ElementName
  • 从 MVC 控制器返回 JSON 字符串

    我使用以下代码将对象发送 接收到我的 mvc 控制器 ajax url createOrUpdateTimeRecord data JSON stringify data type POST dataType json contentTyp
  • 在 Windows 10 上构建 Autodesk Forge RCDB 失败并出现 node-gyp 错误

    尝试构建 Forge 响应式连接数据库时 我无法在我的 Windows 10 计算机上构建此应用程序 我无法成功运行 npm install 我收到如下错误 我最终尝试使用预先配置的 画布 但它仍然无法让节点应用程序运行 https git
  • WinDbg中出现“SOS版本与您正在调试的CLR版本不匹配”怎么办?

    我的某些应用程序出现问题 它是一个基于 wcf 的应用程序 在 Windows 2003 Server x86 的 IIS6 下运行 在事件日志中 我从 W3SVC WP 源 EventID 2262 收到这样的错误 ISAPI C WIN
  • C语言中变量名是如何存储在内存中的?

    在 C 中 假设你有一个名为variable name 假设它位于0xaaaaaaaa 在该内存地址处 您有整数 123 换句话说 variable name包含 123 个 我正在寻找有关措辞的澄清 variable name位于0xaa
  • antd上传控件需要action函数,但我不需要它

    我正在使用 ant design 组件 并且有一个上传输入 https ant design components upload https ant design components upload 根据文档 需要对道具进行操作 但是 我不
  • HTML 5 视频自定义控件

    与许多 Web 开发人员一样 我期待着利用新的 HTML 5 进行流式传输视频
  • 如何在 Foundry 中回滚数据集事务?

    我在 Foundry 上有一个增量数据集 并且上传了一个包含不正确数据的文件 如何反转此事务以便我可以使用正确的数据更新数据集 您可以使用 Foundry 的 Catalog API 您首先需要找到要恢复到的事务的资源 ID rid 当您在
  • Conda 无法在 Powershell 中激活

    我已经在我的 Windows 10 笔记本电脑上安装了 anaconda 我正在尝试激活名为的Python环境pyenv 首先 我检查conda env list在我的笔记本电脑中 这是 powershell 上的输出 PS C Users
  • 图像上的 JQuery 加载事件

    我想在加载图像时将图像父级的大小调整为与图像相同的大小 此时我正在使用这段代码 window load function image principale each function this parent css height this
  • CSS 圆角

    我见过很多这方面的代码 但似乎没有一个能很好地工作或根本无法工作 我已经将图片用于圆角 但我需要代码 以便它能够围绕圆角 table 我找到的解决这个问题的唯一解决方案是在边框周围的单元格中添加图像 我还能尝试什么吗 Try selecto
  • 为什么我收到错误“错误 C2259:...无法实例化抽象类”?

    任何帮助都是appriced 我正在研究 C 工厂模式 但收到此错误 1 gt c users brian documents visual studio 2010 projects cst276lab 3 guitar hpp 456 错
  • Ruby + Rspec:我应该如何测试 attr_accessor?

    我有一个ReturnItem class specs require spec helper describe ReturnItem do is this enough it should respond to chosen it shou
  • 为什么我的 UITableView 顶部有额外的填充,样式为 UITableViewStyleGrouped 在 iOS7 中

    从 iOS7 开始 我的顶部有额外的空间UITableView有一种风格UITableViewStyleGrouped 这是一个例子 tableview从第一个箭头开始 有35个像素的不明填充 然后绿色标题是UIView由返回viewFor
  • 具有漫反射和法线贴图纹理的 3D 模型

    我想使用 libgdx 的资源加载器加载具有漫反射纹理和法线贴图的 3D 模型 据我所知 fbx 以及转换后的 g3dj g3db 格式可以包含漫反射纹理 正如我在 fbx conv 示例中看到的那样 骑士 g3db 如何为其添加法线贴图纹
  • 如何使用 Kotlin 在 ListAdapter 中使用 Filterable?

    我会用一个SearchView过滤我的RecyclerView 在 stackoverflow 和其他网站上我发现只是使用的示例Filterable与 Java 和RecyclerView Adapter当我使用时ListAdapter 所