MVVM Recyclerview 实时数据室 SearchView

2023-12-29

我正在做database应用程序使用room, mvvm, livedata。我已经用一些数据预填充了它。现在我有两个选择,要么我将在应用程序打开时显示预先填充的数据recyclerview或当我使用搜索时显示它SearchView在recyclerView里面。
The Problem当我搜索特定项目时,itw 在我完成单词时显示该项目,并且当我尝试返回我的 resView 为空或它始终保留在该项目上时。我想找个时间试试realtime就像:当我只输入一个字母表时,它显示所有建议都属于字母表,我只想更新livedata
我有什么尝试?
1-> 我已经尝试过了switchMapliveData但我必须刷新我的活动才能取回我的列表。
2-> 我尝试过 resView 过滤器,但没有成功,因为我正在使用 livedata 来更新我的 UI,并且定期尝试不使用livedata它仍然不起作用。
3-> 我尝试过常规editText只是尝试一下,但我发现它没有用,因为面临同样的问题,我的主要重点是searchView
回收者查看代码 使用可过滤或忽略可过滤部分根本不是一个好的尝试

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

        }
    }
}

视图模型

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 类

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

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MVVM Recyclerview 实时数据室 SearchView 的相关文章

随机推荐