我正在使用room, mvvm, livedata
制作database应用。我已经预先填充了一些数据。现在,我有两个选择,要么当我通过recyclerview
打开应用程序时显示该预先填充的数据,要么当我在recyclerView中使用SearchView
搜索它时显示该数据。问题是当我搜索特定项目时,当我完成我的单词时,当我尝试返回resView back空或它始终停留在该项目上时,它将显示该项目。我想尝试某个时间[[实时,例如:当我仅输入一个字母时,它显示所有建议均属于字母,我只想使用livedata
更新我尝试了什么?1->我已经尝试过与switchMap
一起使用的liveData
,但是我必须刷新自己的活动才能重新获得列表。2->我尝试过resView过滤器,该过滤器不起作用,因为我正在使用livedata来更新我的UI,并且在没有livedata
的情况下对其进行了定期尝试,但它也仍然不起作用。3->我尝试了常规的editText
只是为了尝试,但是由于遇到相同的问题我没有发现它有用,我的主要重点是searchView
RecyclerView代码 具有可过滤的内容或只是忽略了可过滤的部分,根本不是很好的尝试
class MyAdapter(
private var context: Context,
private var dataList: List<SearchPojo>
) : RecyclerView.Adapter<MyAdapter.BaseViewHolder<*>>(), Filterable {
private var exampleListFull: List<SearchPojo>? = null
init {
exampleListFull = ArrayList(dataList)
}
companion object {
const val SEARCH_TYPE = 1
}
abstract class BaseViewHolder<T>(view: View) : RecyclerView.ViewHolder(view) {
abstract fun bind(t: T)
}
inner class SearchViewHolder(view: View) : BaseViewHolder<SearchPojo>(view) {
private val userID: TextView = view.findViewById(R.id.idSearch)
private val userName: TextView = view.findViewById(R.id.nameSearch)
private val userPos: TextView = view.findViewById(R.id.positionSearch)
override fun bind(t: SearchPojo) {
userID.text = t.id
userName.text = t.userName
userPos.text = t.position
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {
return when (viewType) {
SEARCH_TYPE -> {
val view =
LayoutInflater.from(context).inflate(R.layout.layout_show_data, parent, false)
SearchViewHolder(view)
}
else -> {
throw IllegalAccessException("In valid View Type")
}
}
}
override fun getItemCount(): Int {
return dataList.size
}
override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) {
val element = dataList[position]
when (holder) {
is SearchViewHolder -> {
holder.bind(element)
}
}
}
override fun getItemViewType(position: Int): Int {
return when (dataList[position]) {
is SearchPojo -> SEARCH_TYPE
else -> throw IllegalAccessException()
}
}
override fun getFilter(): Filter {
return exampleFilter
}
private var exampleFilter = object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val filteredList = ArrayList<SearchPojo>()
if (constraint == null || constraint.isEmpty()) {
filteredList.addAll(exampleListFull as Iterable<SearchPojo>)
} else {
val filterPattern = constraint.toString().toLowerCase().trim { it <= ' ' }
for (item in exampleListFull!!) {
if (item.userName.toLowerCase().contains(filterPattern)) {
filteredList.add(item)
}
}
}
val results = FilterResults()
results.values = filteredList
return results
}
override fun publishResults(constraint: CharSequence, results: FilterResults) {
dataList.clear()
dataList.addAll(results.values as List<SearchPojo>)
notifyDataSetChanged()
}
}
}
主要活动
class MainActivity : AppCompatActivity() { lateinit var searchViewModel: SearchViewModel lateinit var myAdapter: MyAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (!::searchViewModel.isInitialized) { searchViewModel = ViewModelProviders.of(this)[SearchViewModel::class.java] searchViewModel.getAll().observe(this, Observer { myAdapter(it) }) } searchItems.addTextChangedListener(object : TextWatcher { override fun afterTextChanged(s: Editable?) { } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { nameFromDb(s.toString()) } }) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.search_item, menu) val searchItem = menu!!.findItem(R.id.search_menu) val searchView = searchItem.actionView as SearchView searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String?): Boolean { return false } override fun onQueryTextChange(newText: String?): Boolean { myAdapter.getFilter().filter(newText) return true } }) return super.onCreateOptionsMenu(menu) } override fun onOptionsItemSelected(item: MenuItem?): Boolean { when (item!!.itemId) { R.id.refresh -> { val intent = Intent(this, MainActivity::class.java) startActivity(intent) } } return true } private fun nameFromDb(searchTxt: String) { searchViewModel = ViewModelProviders.of(this)[SearchViewModel::class.java] searchViewModel.items.observe(this, object : Observer<List<SearchPojo>> { override fun onChanged(t: List<SearchPojo>?) { if (t == null) { return } myAdapter(t) } }) searchViewModel.searchIt(searchTxt) } private fun myAdapter(t: List<SearchPojo>) { searchResultResView.apply { layoutManager = LinearLayoutManager(context) myAdapter = MyAdapter(this@MainActivity, t) adapter = myAdapter } } }
ViewModel
lass SearchViewModel(application: Application) : AndroidViewModel(application) { private val repo: SearchRepo = SearchRepo(application) private val _searchItem : MutableLiveData<String> = MutableLiveData() val items : LiveData<List<SearchPojo>> = Transformations.switchMap(_searchItem) { myItems -> repo.searchItem(myItems) } init { _searchItem.value = "" } fun searchIt(items: String) { _searchItem.value = items } fun getAll() = repo.allSearch() }
存储库
class SearchRepo(application: Application) { private val searchDao: SearchDao init { val db = SearchDb.instance(application) searchDao = db.searchDao() } fun searchItem(id: String): LiveData<List<SearchPojo>> { return searchDao.searchViaID(id) } fun allSearch() : LiveData<List<SearchPojo>> { return searchDao.allSearch() } }
Dao
@Dao abstract class SearchDao : BaseDao<SearchPojo> { @Query("Select * from SearchPojo") abstract fun allSearch(): LiveData<List<SearchPojo>> @Query("Select * from SearchPojo where userName Like :userNameSearch or LOWER(userName) like LOWER(:userNameSearch)") abstract fun searchViaID(userNameSearch: String) : LiveData<List<SearchPojo>> @Insert abstract override fun insert(searchPojo: SearchPojo) }
@Dao
abstract class SearchDao : BaseDao<SearchPojo> {
@Query("Select * from SearchPojo")
abstract fun allSearch(): LiveData<List<SearchPojo>>
@Query("Select * from SearchPojo where userName GLOB '*' || :userNameSearch|| '*'")
abstract fun searchViaID(userNameSearch: String) : LiveData<List<SearchPojo>>
@Insert
abstract override fun insert(searchPojo: SearchPojo)
}