简体   繁体   English

MVVM Recyclerview Livedata Room SearchView

[英]MVVM Recyclerview Livedata Room SearchView

I am making database app using room, mvvm, livedata .我正在使用room, mvvm, livedata制作数据库应用程序。 I have Prepopulated it with some data.我已经用一些数据预先填充了它。 Now i have two options either i am going to show that prepoulated data when app turns on via recyclerview or show it when i search it using SearchView inside recyclerView.现在我有两个选项,要么我将在应用程序通过recyclerview打开时显示预填充数据,要么在我使用 recyclerView 中的SearchView搜索它时显示它。
The Problem is when i search for particular item, itw shows that item when i complete my word and when i try to go back either my resView back empty or it always stays on that item.问题是当我搜索特定项目时,当我完成我的单词时它会显示该项目,当我尝试 go 将我的 resView 返回为空或它始终停留在该项目上时。 i wanna try sometime realtime like: when i enter only one alphabet it show all the suggestions belongs to alphabet, i only want to update with livedata我想实时尝试一下:当我只输入一个字母表时,它显示所有建议都属于字母表,我只想用livedata更新
What i have try?我有什么尝试?
1-> I have already tried switchMap which worked with liveData but i have to refresh my activity in order to get back my list. 1-> 我已经尝试过使用switchMapliveData ,但我必须刷新我的活动才能取回我的列表。
2-> I have tried resView filter which didn't worked because i am using livedata to update my UI and also give it regular try without livedata it still didn't work either. 2-> 我尝试了 resView 过滤器,但它不起作用,因为我正在使用 livedata 更新我的 UI,并且在没有livedata的情况下定期尝试它仍然不起作用。
3-> I Have tried regular editText just to try but i didn't find it useful as facing same problem, my main focus was on searchView 3->我尝试过常规editText只是为了尝试,但我发现它没有用,因为面临同样的问题,我的主要关注点是searchView
RecyclerView code with filterable or just ignore filterable part it wasn't good try at all带有可过滤的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()
        }
    }

}

Main Activity主要活动

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

Repository存储库

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)

}

Please change your @Dao class like this请像这样更改您的@Dao class

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RecyclerView 不创建项目 - (MVVM + Room + LiveData) - RecyclerView not creating items - ( MVVM + Room + LiveData) 如何在 Room 中将 SearchView 与 LiveData 和 ViewModel 一起使用 - How to use SearchView with LiveData and ViewModel in Room Room + ViewModel + LiveData + RecyclerView (MVVM) 第 7 部分 - 添加注意活动 - Android 教程崩溃 - Room + ViewModel + LiveData + RecyclerView (MVVM) Part 7 - ADD NOTE ACTIVITY - Android Tutorial crashes 带有 Room 和 LiveData 的 MVVM - 如何从 LiveData 获取列表 - MVVM with Room and LiveData - How to get List from LiveData Android MVVM + Room 通过其他 LiveData 对象创建 LiveData RecyclerViewItem 对象 - Android MVVM + Room creating LiveData RecyclerViewItem objects by other LiveData objects 如何在 MVVM 架构中观察 RecyclerView 适配器中的 LiveData? - How to observe LiveData in RecyclerView adapter in MVVM architecture? 使用Livedata时如何将Filter SearchView用于RecyclerView? - How to use Filter SearchView for RecyclerView when using Livedata? 使用SearchView使用LiveData内容过滤RecyclerView的列表 - Filtering RecyclerView's list with LiveData content using SearchView 如何在使用Room Livedata MVVM时显示LoadingState - How to show LoadingState when using Room Livedata MVVM 在Recylerview中实现复选框。 MVVM Room ViewModel LiveData Recylerview复选框 - Implementing checkbox in a Recylerview. MVVM Room ViewModel LiveData Recylerview Checkbox
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM