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

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

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

  1. 创建了如下搜索栏:

  1. 我在 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
        }
    }
  1. 我的适配器类如下:
    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

【问题讨论】:

    标签: android android-recyclerview rx-java android-mvvm android-filterable


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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      • 2018-10-29
      • 1970-01-01
      相关资源
      最近更新 更多