RecyclerView未使用filterList

时间:2019-07-16 04:19:49

标签: android kotlin

我正在将代码迁移到Kotlin,我的活动之一是使用带有自定义SearchListAdapter的ListView。 我写了一个新的RecyclerViewAdapter,它也执行搜索过滤。

在调试时,我发现列表已被过滤,但视图未更新。我想念什么?

我也无法访问handleItemClick()中的项目位置,而只能访问项目属性。

RecyclerAdapter.kt

package com.example.ui

import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Filter
import android.widget.Filterable
import kotlinx.android.synthetic.main.activity_display_list_item_r.view.*
import com.example.items.Items_r
import com.example.R

class RecyclerAdapter(private val itemList: MutableList<Items_r>, private val clickListener: (Items_r) -> Unit) :
  RecyclerView.Adapter<RecyclerView.ViewHolder>(), Filterable {

  private var searchList: List<Items_r>? = null

  class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(item: Items_r, clickListener: (Items_r) -> Unit) {
      itemView.list_item_title.text = item.itemName
      itemView.setOnClickListener { clickListener(item)}
    }
  }

  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val view = inflater.inflate(R.layout.activity_display_list_item_r, parent, false)
    return ItemViewHolder(view)
  }

  override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    (holder as ItemViewHolder).bind(itemList[position], clickListener)
  }

  override fun getItemCount() = itemList.size

  override fun getFilter(): Filter {
    return object : Filter() {
      override fun performFiltering(charSequence: CharSequence): FilterResults {
        val charString = charSequence.toString()
        if (charString.isEmpty()) {
          searchList = itemList
        } else {
          val filteredList = ArrayList<Items_r>()
          for (row in itemList) {

            if (row.itemName.toLowerCase().contains(charString.toLowerCase())) {
              filteredList.add(row)
            }
          }

          searchList = filteredList
        }

        val filterResults = FilterResults()
        filterResults.values = searchList
        return filterResults
      }

      override fun publishResults(charSequence: CharSequence, filterResults: FilterResults) {
        searchList = filterResults.values as ArrayList<Items_r>
        notifyDataSetChanged()
      }
    }
  }

}

SampleActivity.kt

package com.example.ui

import android.app.Activity
import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.widget.SearchView
import androidx.core.app.NavUtils
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.Menu
import android.view.MenuItem
import androidx.recyclerview.widget.DividerItemDecoration
import butterknife.ButterKnife
import com.example.items.Items_r
import com.example.R
import com.example.ui.base.BaseActivity
import kotlinx.android.synthetic.main.activity_display_list_r.*

class SampleActivity : BaseActivity() {
    private var caller = ""
    private var callerClass: Class<*>? = null

    private var rAdapter: RecyclerAdapter? = null
    private var searchView: SearchView? = null

    /* Access modifiers changed, original: protected */
    override val selfNavDrawerItem: Int
        get() = R.id.title_activity_sample

    override fun providesActivityToolbar(): Boolean {
        return true
    }

    /* Access modifiers changed, original: protected */
    public override fun onCreate(bundle: Bundle?) {
        super.onCreate(bundle)
        setContentView(R.layout.activity_display_list_r)
        ButterKnife.bind(this as Activity)
        setupToolbar()

        val stringArray = resources.getStringArray(R.array.list_sample)
        val searchList = ArrayList<Items_r>()
        for (items in stringArray) {
            searchList.add(Items_r(items))
        }

        rAdapter = RecyclerAdapter(searchList, { i : Items_r -> handleItemClick(i) })
        main_recyclerview.layoutManager = LinearLayoutManager(this)
        main_recyclerview.setHasFixedSize(true)
        main_recyclerview.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
        main_recyclerview.adapter = rAdapter

    }

    private fun handleItemClick(i: Items_r) {
        val intent = Intent(this, LocalActivity::class.java)
        val stringBuilder = StringBuilder()
        stringBuilder.append("file:///android_asset/samples/")
        stringBuilder.append(i.itemName)
        stringBuilder.append(".html")
        intent.putExtra("WEBSITE_URL", stringBuilder.toString())
        startActivity(intent)
    }

    private fun setupToolbar() {
        val actionBarToolbar = getActionBarToolbar()
        actionBarToolbar!!.setHomeAsUpIndicator(R.mipmap.ic_menu)
        actionBarToolbar.setDisplayHomeAsUpEnabled(true)
    }

    override fun onOptionsItemSelected(menuItem: MenuItem): Boolean {
        if (menuItem.itemId != R.id.title_home) {
            return super.onOptionsItemSelected(menuItem)
        }
        openDrawer()
        return true
    }

    override fun onBackPressed() {
        this.caller = "com.example.ui.MainActivity"
        try {
            this.callerClass = Class.forName(this.caller)
        } catch (e: ClassNotFoundException) {
            e.printStackTrace()
        }

        NavUtils.navigateUpTo(this, Intent(this, this.callerClass))
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.search_menu, menu)
        val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
        searchView = menu.findItem(R.id.menu_item_search).actionView as SearchView
        searchView!!.setSearchableInfo(searchManager.getSearchableInfo(componentName))
        //searchView!!.setSubmitButtonEnabled(true)

        searchView!!.setOnQueryTextListener(object: SearchView.OnQueryTextListener {

            override fun onQueryTextSubmit(query: String): Boolean {
                rAdapter!!.filter.filter(query)
                return false
            }

            override fun onQueryTextChange(query: String): Boolean {
                rAdapter!!.filter.filter(query)
                return false
            }

        })

        return super.onCreateOptionsMenu(menu)
    }
}

Items_r.kt模型

package com.example.items

data class Items_r ( val itemName: String)

字符串数组

    <string-array name="list_sample">
        <item>Alpha</item>
        <item>Beta</item>
        <item>Charlie</item>
        <item>Delta</item>
        <item>Alpha Romeo</item>
        <item>Beta Gamma</item>
    </string-array>

2 个答案:

答案 0 :(得分:1)

您正在使用itemList绑定数据

 override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    (holder as ItemViewHolder).bind(itemList[position], clickListener)
  }

但是,您更新了searchList,它不会影响适配器中数据的任何部分。您需要在itemList

中更新publishResults

答案 1 :(得分:0)

更新了我的适配器代码,现在可以使用。我仍然不确定为什么即使我改变了对searchList的操作,它还是不能更早地工作

  private var searchList: List<Items>? = null

  inner class RecyclerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    var itemTitle: TextView? = null

    init {
      itemTitle = view.findViewById(R.id.list_item_title)
      view.setTag(this);
      view.setOnClickListener {
        clickListener.onItemClicked(searchList!![adapterPosition], itemList.indexOf(searchList!![adapterPosition]))
      }
    }
  }


  init {
    this.searchList = itemList
  }

  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    // Inflate XML. Last parameter: don't immediately attach new view to the parent view group
    val itemView = inflater.inflate(R.layout.activity_display_item_text, parent, false)

    return RecyclerViewHolder(itemView)
  }

  override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
    val item = searchList!![position]
    holder.itemTitle!!.text = item.itemName
  }

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

更新了我的活动以匹配适配器代码,并且还使用适配器中的setTag传递了商品的位置。

{
    val stringArray = resources.getStringArray(R.array.list_sample)
    val itemList = ArrayList<Items>()
    for (items in stringArray) {
        itemList.add(Items(items))
    }
    rAdapter = RecyclerAdapter(itemList, this)

    main_recyclerview.layoutManager = LinearLayoutManager(this)
    main_recyclerview.setHasFixedSize(true)
    main_recyclerview.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
    main_recyclerview.itemAnimator = DefaultItemAnimator()
    main_recyclerview.adapter = rAdapter
}

override fun onItemClicked(item: Items, position: Int) {
    val intent = Intent(this, LocalActivity::class.java)
    val stringBuilder = StringBuilder()
    stringBuilder.append("file:///android_asset/samples/")
    stringBuilder.append(position)
    stringBuilder.append(".html")
    intent.putExtra("WEBSITE_URL", stringBuilder.toString())
    startActivity(intent)
}