【问题标题】:Android LiveData: How to do an ArrayList<LiveData<RetrofitObject>>?Android LiveData:如何执行 ArrayList<LiveData<RetrofitObject>>?
【发布时间】:2020-09-18 06:44:19
【问题描述】:

我正在使用 MVVM 架构创建应用程序,但遇到了获取要在视图中显示的 LiveData 列表的问题。

在我的 ViewModel 中,我有一个 getAll() 函数,它使用 Room 从数据库中检索字符串列表。从那里,我得到字符串并调用我的 Retrofit 函数将每个字符串单独发送到返回对象的 Web 服务器。这是我的问题发生的地方。

从我在网上看到的 MVVM 教程中,它们通常具有 LiveData> 样式,但由于我单独获取每个对象,因此它变为 List> 但我认为这不是正确的做法,因为在我的查看我需要执行 ForEach 循环来观察列表中的每个 LiveData 对象。

我尝试了其他解决方法,但似乎不起作用。有更好的方法吗?

@Query("SELECT * FROM table")
    fun getAll(): LiveData<List<String>>

存储库

fun getAll(): LiveData<List<String>> {
        return dao.getAll()
    }

fun getRetrofitObject(s: String): LiveData<RetrofitObject> {
        api = jsonApi.getRetrofitObjectInfo(s, API_KEY)
        val retrofitObject: MutableLiveData<RetrofitObject> = MutableLiveData()
        api.enqueue(object : Callback<RetrofitObject> {
            override fun onFailure(call: Call<RetrofitObject>?, t: Throwable?) {
                Log.d("TEST", "Code: " + t.toString())
            }

            override fun onResponse(call: Call<RetrofitObject>?, response: Response<RetrofitObject>?) {
                if (response!!.isSuccessful) {
                    retrofitObject.value = response.body()
                }
            }
        })
        return retrofitObject
    }

MainActivityViewModel(视图模型)

var objectList ArrayList<LiveData<retrofitObject>> = ArrayList() 

// This is getting objects using Retrofit
fun getRetrofitObject(s: String): LiveData<retrofitObject> {
        return repo.getRetrofitObject(s)
    }

// This is getting all the strings from the internal database
fun getAll(): ArrayList<LiveData<retroFitObject>> {
        repo.getAll().value?.forEach {it ->
            objectList.add(getRetrofitObject(it)) //How else would I be able to do this?
        }
        return objectList
    }

MainActivity(视图)

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mainActivityViewModel.getAll().forEach {
                        it.observe(this, Observer {it ->
                            mainActivityViewModel.objectList.add(it) //Here is part of the issue since I don't want to use a forloop in the View

                        })
                    }
                    adapter.objectList = mainActivityViewModel.objectList
                    recyclerView.adapter = adapter
}

谢谢,如果有其他需要或困惑,请告诉我!

【问题讨论】:

  • 你试过List&lt;&gt;而不是Arraylist&lt;&gt;吗?
  • 是的,我有@DetainedDeveloper

标签: android kotlin mvvm retrofit android-livedata


【解决方案1】:

可能还有其他我不知道的方法。

但是您可以使用转换来处理情况,有关更多信息,请查看文档页面。 Transformations.switchMap(LiveData trigger, Function> func)

您不必将实时数据观察器放入 for 循环中。

【讨论】:

    【解决方案2】:

    通过查看上面的代码,您尝试从服务器获取每个表行的项目列表,并尝试将结果更新到您的回收站视图。你的逻辑有点混乱.. 所以在你的活动中..首先初始化你的适配器和 recyclerview

    然后调用您的 viewmodel 函数以获取表中的所有值,并进行循环以在后台调用您的网络线程函数并将值存储在实时数据对象中。

    只需在您的活动/片段中观察此实时数据,然后将列表传递给适配器并通知它。通过这样做,每当您的实时数据发生更改时,您的回收站视图也会反映项目

    您的代码的问题是,您被称为带有 enque 选项的改造网络函数及其后台线程进程。因此,代码不会等待网络完成。它会返回retrofitObject的数据。但是它还没有得到数据。所以这会出错。

    【讨论】:

    • 那么 LiveData 会在 ArrayList 中还是 LiveData
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2020-03-05
    • 2021-07-16
    相关资源
    最近更新 更多