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 的相关文章

  • 如何获取每个StorageVolume的可用大小和总大小?

    背景 谷歌 悲伤 计划破坏存储权限 https www xda developers com android q storage access framework scoped storage 这样应用程序将无法使用标准文件 API 和文件
  • 我在布局上看不到任何 FirebaseRecyclerAdapter 项目

    我试图将数据从 Firebase 数据库检索到我的布局 但我看不到任何项目FirebaseRecyclerAdapter在布局中 请帮忙 我按照一个教程展示了如何做到这一点 当我运行应用程序时 我没有看到任何项目 但我可以滚动 public
  • 如何使用 KClass 反射在 Kotlin 中区分类和接口

    我正在使用 Kotlins KClass 按名称查找类 如下所示 val i KClass lt gt Class forName SampleClass kotlin 但是 我想省略接口 到目前为止 我通过构造函数区分接口和类 val i
  • Android Studio:XML 布局中的“包装在容器中”

    编辑 XML 布局文件时 Eclipse 有一项称为 包裹在容器中 的功能 重新格式化 gt Android gt 可让您选择一个或多个视图并在其周围包裹您选择的布局 Android Studio中有类似的东西吗 目前正在实施中 问题 69
  • Dialog.setTitle 不显示标题

    我正在尝试向我的对话框添加自定义标题 但是每当我运行我的应用程序时 它都不会显示标题 我创建对话框的代码是 final Dialog passwordDialog new Dialog this passwordDialog setCont
  • 以编程方式将文本颜色设置为主要 Android 文本视图

    如何设置我的文本颜色TextView to android textColorPrimary以编程方式 我已经尝试了下面的代码 但它将 textColorPrimary 和 textColorPrimary Inverse 的文本颜色始终设
  • 使用带有 prism 的 MVVM 在视图之间进行更改

    我是 WPF 新手 但根据我所读到的内容 构建应用程序的正确方法是在同一窗口上切换视图 我的意思是类似于带有菜单和显示视图的工作区的 框架 到目前为止我一直在关注这个http jesseliberty com 2011 01 06 wind
  • 当它的父级是 ConstraintLayout 时设计 CardView 吗?

    我在编辑包含Relativelayout的Cardview内的RelativeLayout时搞砸了 ConstraintLayout会将相对布局的wrap content更改为0并添加工具 layout editor absoluteX 1
  • 图像作为电子邮件附件

    我想构建一个应用程序 我可以在电子邮件中附加图像 打开图像并将其设置为我的壁纸 我想让它跨平台 所以你能告诉我是否可以使用phonegap 或者我是否必须为iphone和android构建一个本机应用程序 您好 如果您只想通过电子邮件附加图
  • 从 BroadcastReceiver 类调用活动方法

    我知道我可以做一个内部接收器类来调用接收器中的任何方法 但我的主要活动太大了 要做的事情也很多 因此 我需要一个扩展广播接收器的类 但它不是内部类 并且可以从我的主要活动中调用一种方法 我不知道是否可能 但我的活动是家庭活动和 single
  • okhttp 获取失败响应

    我已经在我的 android 客户端中实现了 okhttp 来进行网络调用 当我收到失败响应时 我会收到失败代码以及与该代码相关的文本作为消息 但我没有收到服务器发送给我的自定义失败响应 在我实施的代码中的失败响应中 我收到的消息只是 错误
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • Mipmap 与可绘制文件夹[重复]

    这个问题在这里已经有答案了 我正在使用 Android Studio 1 1 Preview 1 我注意到 当我创建一个新项目时 我得到以下层次结构 不同 DPI 的 Mipmap 文件夹 不再有不同 DPI 的可绘制文件夹 我应该将所有资
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • 您使用什么物理 Android 设备进行测试?

    有什么好的推荐用于测试目的的物理 Android 设备吗 我正在苹果阵营寻找像 iPod touch 这样的设备 可以帮助 iOS 开发人员测试他们的东西 我知道有 Nexus One 但那东西相当昂贵 而且我并不真正关心手机的东西 而是可
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • Dagger 2 没有生成我的组件类

    我正在使用 Dagger 2 创建我的依赖注入 几个小时前它还在工作 但现在不再生成组件 这是我创建组件的地方 public class App extends Application CacheComponent mCacheCompon
  • 上网本上可以进行Android开发吗? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想使用我的上网本进行 Android 开发 但是当我尝试使用 Eclipse 运行 SDK 时 没有加载任何内容 上网本对于 Android 开发来
  • 如何使用 AccessibilityService 在 Android 中模拟按键

    我正在编写一个辅助服务 我一直在尝试在应用程序上进行一些自动搜索 我使用accessibilityservice action paste来填充EditText 然后我需要模拟软键盘上的按键 但我不知道如何做 你们能帮我一下吗 你可以尝试A
  • 我的应用程序中的后退按钮出现问题[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想在手机关闭时清除共享首选项值 你

随机推荐