在 recyclerview kotlin 上实现搜索的问题

Posted

技术标签:

【中文标题】在 recyclerview kotlin 上实现搜索的问题【英文标题】:Issues implementing search on recycleview kotlin 【发布时间】:2020-04-01 05:58:15 【问题描述】:

我正在尝试在 recyclerview 中实现搜索选项。

到目前为止我已经实现的是:

    创建了如下搜索栏:

    我在 MainActivity 中应用了 onCreateOptions:
    class RecyclerListActivity: AppCompatActivity() 
        private lateinit var binding: ActivityMainBinding
        private lateinit var viewModel: PostListViewModel
        private var errorSnackbar: Snackbar? = null


        private var searchView: SearchView? = null

        override fun onCreate(savedInstanceState: Bundle?)
            super.onCreate(savedInstanceState)

            binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
            binding.postList.layoutManager = GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)

            viewModel = ViewModelProviders.of(this).get(PostListViewModel::class.java)
            viewModel.errorMessage.observe(this, Observer 
                errorMessage -> if(errorMessage != null) showError(errorMessage) else hideError()
            )
            binding.viewModel = viewModel

        

        private fun showError(@StringRes errorMessage:Int)
            errorSnackbar = Snackbar.make(binding.root, errorMessage, Snackbar.LENGTH_INDEFINITE)
            errorSnackbar?.setAction(R.string.retry, viewModel.errorClickListener)
            errorSnackbar?.show()
        

        private fun hideError()
            errorSnackbar?.dismiss()
        


        override fun onCreateOptionsMenu(menu: Menu): Boolean 
            menuInflater.inflate(R.menu.menu_main, menu)
            searchView = menu.findItem(R.id.action_search).actionView as SearchView
            searchView!!.maxWidth = Int.MAX_VALUE
            searchView!!.imeOptions = EditorInfo.IME_ACTION_DONE

            // listening to search query text change
            searchView!!.setOnQueryTextListener(object :
                SearchView.OnQueryTextListener 
                override fun onQueryTextSubmit(query: String): Boolean 
                    return false
                

                override fun onQueryTextChange(query: String): Boolean 
                    return false
                
            )
            return true
        
    
    我的适配器类如下:
    class PostListAdapter: RecyclerView.Adapter<PostListAdapter.ViewHolder>(), Filterable 
        private lateinit var postList:List<Data>
        private lateinit var postListFull:List<Data>

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder 
            val binding: ListItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.list_item, parent, false)
            return ViewHolder(binding)
        

        override fun onBindViewHolder(holder: ViewHolder, position: Int) 
            holder.bind(postList[position])
        

        override fun getItemCount(): Int 
            return if(::postList.isInitialized) postList.size else 0
        

        fun updatePostList(postList:List<Data>)
            this.postList = postList
            notifyDataSetChanged()
        

        class ViewHolder(private val binding: ListItemBinding): RecyclerView.ViewHolder(binding.root)
            private val viewModel = MoviesViewModel()

            fun bind(post:Data)
                viewModel.bind(post)
                binding.viewModel = viewModel
            

            init 
                binding.root.setOnClickListener 
                    //Toast.makeText(binding.root.context, binding.postTitle.text, Toast.LENGTH_SHORT).show()

                    val intent = Intent(binding.root.context, DetailsActivity::class.java)
                    //intent.putExtra(REPO_NAME, binding.postTitle.text)

                    binding.root.context.startActivity(intent)
                
            

        

        override fun getFilter(): Filter? 
            return searchFilter
        

        private val searchFilter: Filter = object : Filter() 
            override fun performFiltering(constraint: CharSequence?): FilterResults? 
                val filteredList: MutableList<Data> = ArrayList()
                if (constraint == null || constraint.isEmpty()) 
                    filteredList.addAll(postListFull)
                 else 
                    val filterPattern =
                        constraint.toString().toLowerCase().trim()
                    for (item in postListFull) 
                        if (item.title.toLowerCase().contains(filterPattern) || item.genre.toLowerCase().contains(filterPattern)) 
                            filteredList.add(item)
                        
                    
                
                val results = FilterResults()
                results.values = filteredList
                return results
            

            override fun publishResults(
                constraint: CharSequence?,
                results: FilterResults
            ) 
                //postList.clear()
                //postList.addAll(results.values as List<*>)
                notifyDataSetChanged()
            
        

我有两个问题需要解决。第一个是:在这些行中获取未解析的引用(适配器类)。我该如何解决?

postList.clear()

postList.addAll(results.values as List<*>) 

第二个是:如何在适配器中应用过滤器结果,因为我使用了匕首和数据绑定?我使用以下教程来创建 recyclerview:https://proandroiddev.com/mvvm-with-kotlin-android-architecture-components-dagger-2-retrofit-and-rxandroid-1a4ebb38c699

【问题讨论】:

【参考方案1】:
 private lateinit var postListFull: ArrayList<Data>= ArrayList()

在 publishResults() 方法中,将结果存储在列表中:

postListFull= results!!.values as ArrayList<Data>
            notifyDataSetChanged()

对于您的第二个问题,您想在哪里应用过滤结果,为什么?

【讨论】:

以上是关于在 recyclerview kotlin 上实现搜索的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用空侦听器在kotlin中的适配器上实现点击侦听器?

Kotlin中实现RecyclerView嵌套RecyclerView

在 Fragment 中使用 RecyclerView 时出现 Kotlin 错误的 Android

使用 Kotlin 在片段中引用 RecyclerView 时出现空指针错误

如何使用 Kotlin 在 RecyclerView Adapter 中实现 onClick 并进行数据绑定

片段内的 RecyclerView 的 Kotlin OnItemClickListener