【问题标题】:How to use LiveData for searching?如何使用 LiveData 进行搜索?
【发布时间】:2020-11-26 17:54:35
【问题描述】:

我有一个 ViewModel,它有一个类 Course 的数组列表的 MutableLiveData

private var coursesList: MutableLiveData<ArrayList<Course>> = MutableLiveData()

这个课程列表充满了从 API 获得的数据(通过改造):coursesList.postValue(response.body())

现在,用户可以按课程名称搜索课程。我的搜索功能是遍历 courseList 的元素并检查其名称是否与用户键入的内容相同。它返回一个数组列表,其中包含以键入的名称开头的课程(此列表稍后发送到一个片段,该片段将其传递给适配器以显示在回收器视图中):

fun getCoursesList(): MutableLiveData<ArrayList<Course>> {
        return coursesList
}

fun searchCourses(searchString: String): ArrayList<Course> {

    val resultsList: ArrayList<Course> = ArrayList()

    if (getCoursesList().value == null) return resultsList

    if (getCoursesList().value!!.size > 0) {
       
        for (course in getCoursesList().value!!.iterator()) {
            if (course.name.toLowerCase(Locale.ROOT).startsWith(searchString)) {
                resultsList.add(course)
            }
        }
    }
    resultsList.sortBy { it.price }
    return resultsList
}

此功能有效,除了我的导师之外,其他所有人都要求我使用 LiveData 进行搜索,但没有提供任何其他提示。

所以我的问题是如何使用 LiveData 进行搜索?我试图寻找答案,我看到一些使用 LiveDataTransformations.switchMap 但他们都在使用 RoomDAO,我无法将其调整为我拥有的代码。

任何帮助将不胜感激。提前致谢。

【问题讨论】:

    标签: android kotlin viewmodel android-livedata mutablelivedata


    【解决方案1】:

    也许对你有一点帮助,

    class YourViewModel(
       private val courcesRepository: CourcesRepository
    ) : ViewModel() {
    
    // Private access - mutableLiveData!
    private val _coursesList = MutableLiveData<ArrayList<Course>>()
    
    // Public access - immutableLiveData
    val coursesList: LiveData<ArrayList<Course>>
        get() = _coursesList
    
    init {
        // mutableLiveData initialize, automatic is immutable also initialize
        _coursesList.postValue(getCourses())
    }
    
    // Here you get your data from repository
    private fun getCourses(): ArrayList<Course> {
        return courcesRepository.getCources()
    }
    
    // Search function
    fun searchCourses(searchString: String) {
    
        // you hold your data into this methode
        val list: ArrayList<Course> = getCources()
    
        if (searchString.isEmpty()) {
    
            // here you reset the data if search string is empty
            _coursesList.postValue(list)
        } else {
    
            // here you can search the list and post the new one to your LiveData
            val filterList = list.filter {
                it.name.toLowerCase(Locale.ROOT).startsWith(searchString)
            }
            filterList.sortedBy { it.price }
            _coursesList.postValue(filterList)
        }
    }
    
    }
    

    第一个提示是您应该使用如下所示的 LiveData,这也是 google 的喷气背包团队推荐的。原因是你可以封装 LivaData。

    第二个提示是您应该使用 kotlin 的惯用方式来过滤列表。您的代码可读且速度更快。

    至少创建一个存储库类来分离应用程序中的关注点是个好主意。

    还有一些对你有用的链接:

    https://developer.android.com/jetpack/guide

    https://developer.android.com/topic/libraries/architecture/livedata

    希望对你有帮助

    【讨论】:

    • 非常感谢 Ioannis!我现在很清楚我必须做什么。
    • 很高兴帮助你,Iva!
    【解决方案2】:

    Ii 很难猜出期望的结果,但一种可能的解决方案是也使用实时数据来搜索字符串。然后将它们与 courseList 实时数据组合成搜索课程的实时数据,例如这样。

        val searchStringLiveData: MutableLiveData<String> = MutableLiveData()
        val coursesListLiveData: MutableLiveData<ArrayList<Course>> = MutableLiveData()
        val searchedCourses: MediatorLiveData<ArrayList<Course>> = MediatorLiveData()
    
        init {
            searchedCourses.addSource(searchStringLiveData) {
                searchedCourses.value = combineLiveData(searchStringLiveData, coursesListLiveData)
            }
            searchedCourses.addSource(coursesListLiveData) {
                searchedCourses.value = combineLiveData(searchStringLiveData, coursesListLiveData)
            }
        }
    
    
        fun combineLiveData(searchStringLiveData: LiveData<String>, coursesListLiveData: LiveData<ArrayList<Course>> ): ArrayList<Course> {
            // your logic here to filter courses
            return ArrayList()
        }
    

    我还没有运行代码,所以我不能 100% 确定它是否有效,但我的想法是每次两个实时数据中的任何一个更改值、搜索字符串或课程时,都会执行组合函数并得到结果设置为 searchedCourses 中介实时数据的值。为了简单起见,我也省略了过滤的逻辑。

    【讨论】:

      猜你喜欢
      • 2016-05-31
      • 2014-08-27
      • 2016-03-28
      • 1970-01-01
      • 2014-11-29
      • 2020-12-15
      • 2015-03-05
      • 2023-03-19
      • 1970-01-01
      相关资源
      最近更新 更多