gpt4 book ai didi

android - 从 ViewModel 中的服务器获取数据后,LiveData Observer 不会更新 UI

转载 作者:行者123 更新时间:2023-11-29 18:27:18 30 4
gpt4 key购买 nike

我正在尝试使用 retrofit get 请求从服务器获取数据,在 ViewModel 中,我发起请求,请求的 OnResponse 方法显示数据已成功从服务器检索,但 fragment 中的观察者没有获取更新。我正在分享下面的代码。

改造 API 调用

fun getGenres(application: Context,callback:(List<Genre>)->Unit){
val baseURL = "https://listen-api.listennotes.com/"
var genreList: MutableLiveData<List<Genre>> =MutableLiveData()
val logging = HttpLoggingInterceptor()
// set your desired log level
logging.level = HttpLoggingInterceptor.Level.BODY

val httpClient = OkHttpClient.Builder()
// add your other interceptors …
// add logging as last interceptor
httpClient.addInterceptor(logging)

val gson = GsonBuilder()
.setLenient()
.create()

val retrofit = Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(httpClient.build())
.build()

val api: ApiFunctions = retrofit.create(ApiFunctions::class.java)



val call: Call<PodcastGetCategoryResponse> = api.getGenres()

call.enqueue(object : Callback<PodcastGetCategoryResponse> {
override fun onFailure(call: Call<PodcastGetCategoryResponse>, t: Throwable) {

Toast.makeText(application, "failure" + t.stackTrace, Toast.LENGTH_SHORT).show()

}

override fun onResponse(
call: Call<PodcastGetCategoryResponse>,
response: Response<PodcastGetCategoryResponse>
) {


response.body().apply {
callback(this?.genres!!) }
Toast.makeText(application, "success: ${response.body()?.genres?.size}", Toast.LENGTH_SHORT).show()

}

})

return genreList;
}

这会成功运行并从服务器检索流派列表。

View 模型类

class CategoryViewModel(application: Application) : AndroidViewModel(application) {
private val rootJob = SupervisorJob()

private val coroutineContext: CoroutineContext
get() = Dispatchers.Main + rootJob

var listOfCategory: MutableLiveData<List<Genre>> = MutableLiveData()

init {
getistOfCategory()
}

// this method is responsible for retrieving data from the result of the API call method using a coroutine.

fun getistOfCategory() {
CoroutineScope(coroutineContext).launch() {
ApiFunctions.getGenres(getApplication<Application>(), { l -> listOfCategory.value = l } )
listOfCategory.postValue(listOfCategory.value)
}
}

我认为问题出在这个类上,但我想不通。

** fragment 类**

class MainFragment : Fragment() {
private lateinit var viewModel: CategoryViewModel
private lateinit var binding: FragmentMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(CategoryViewModel::class.java)
viewModel.getistOfCategory()

}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {

binding =DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
var myView: View = binding.root




viewModel.listOfCategory.observe(this,
Observer { list ->
Toast.makeText(
context,
"Data Changed" + list?.size,
Toast.LENGTH_LONG
).show()
})

return myView
}

我想要的是,当从服务器检索到新值时,它应该保存在 ViewModel 类的 LiveData 中, fragment 应该成功地观察到它们。

最佳答案

根据您当前的实现,listOfCategory 的值会随着每次更新而不断变化。这意味着当您的列表更新时,观察者不会收到通知,因为他们正在观察另一个 LiveData 对象(在更新发生之前已分配给您的引用)您需要确保仅实例化 liveData 对象一次,并在获得更新时更新其值。

你的代码应该是这样的

fun getGenres(application: Context, callback:(List<Genre>)->Unit){
...
response.body().apply {
callback(this?.genres!!)
}
...
}



fun getistOfCategory(): {
CoroutineScope(coroutineContext).launch() {
ApiFunctions.getGenres(getApplication<Application>(), l -> listOfCategory.value = l)
}

}

关于android - 从 ViewModel 中的服务器获取数据后,LiveData Observer 不会更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58163453/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com