MVVM Recyclerview Livedata Room SearchView

问题描述 投票:0回答:1

我正在使用room, mvvm, livedata制作database应用。我已经预先填充了一些数据。现在,我有两个选择,要么当我通过recyclerview打开应用程序时显示该预先填充的数据,要么当我在recyclerView中使用SearchView搜索它时显示该数据。问题是当我搜索特定项目时,当我完成我的单词时,当我尝试返回resView back空或它始终停留在该项目上时,它将显示该项目。我想尝试某个时间[[实时,例如:当我仅输入一个字母时,它显示所有建议均属于字母,我只想使用livedata更新我尝试了什么?1->我已经尝试过与switchMap一起使用的liveData,但是我必须刷新自己的活动才能重新获得列表。2->我尝试过resView过滤器,该过滤器不起作用,因为我正在使用livedata来更新我的UI,并且在没有livedata的情况下对其进行了定期尝试,但它也仍然不起作用。3->我尝试了常规的editText只是为了尝试,但是由于遇到相同的问题我没有发现它有用,我的主要重点是searchViewRecyclerView代码 具有可过滤的内容或只是忽略了可过滤的部分,根本不是很好的尝试

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) }
android kotlin mvvm android-recyclerview searchview
1个回答
0
投票
请像这样更改您的@Dao班级

@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) }

© www.soinside.com 2019 - 2024. All rights reserved.