如何将信息从 MutableLiveData<Resource<Object>> 提取到视图模型中的更简单对象
How to extract the information from MutableLiveData<Resource<Object>> to a simpler object in viewmodel
我正在尝试在我的 HomeFragment 中从 MutableLiveData<Resource<ObjectIWant>>
获取一个对象到 var hereIwantTheObject : ObjectIWant
,如果您使用协程和 LiveData,显然使用资源 class 是推荐的方法。问题是我希望这个对象在我的变量上并与 MutableLiveData 分离,当我尝试它时它说变量尚未初始化。这是我的 classes 和我尝试过的
ViewModel class:
class HomeFragmentViewModel : ViewModel() {
val mutableVar: MutableLiveData<Resource<ObjectIwant>> = MutableLiveData()
init {
getObjectIwantData()
}
fun getObjectIwantData() = viewModelScope.launch {
mutableVar.postValue(Resource.Loading())
val response = AppRepository().getObjectIwantDataInRepository()
mutableVar.postValue(handleResponse(response))
}
private fun handleResponse(response: Response<ObjectIwant>): Resource<ObjectIwant> {
if (response.isSuccessful) {
response.body()?.let { resultResponse ->
return Resource.Success(resultResponse)
}
}
return Resource.Error(response.message())
}
HomeFragment class 以及我试图获取信息的位置:
class HomeFragment : Fragment() {
lateinit var viewModel: HomeFragmentViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
viewModel = ViewModelProvider(this).get(HomeFragmentViewModel::class.java)
binding.lifecycleOwner = this
var hereIwantTheObject: ObjectIwant? = null
viewModel.brastlewarkTownData.observe(viewLifecycleOwner, Observer { response ->
response.data?.let { brastlewarkTown ->
hereIwantTheObject = brastlewarkTown
}
})
Log.i(TAG, "onCreateView: ${hereIwantTheObject!!.name")
return binding.root
}
}
这里是资源 class:
sealed class Resource<T>(
val data: T? = null,
val message: String? = null
) {
class Success<T>(data: T) : Resource<T>(data)
class Error<T>(message: String, data: T? = null) : Resource<T>(data, message)
class Loading<T> : Resource<T>()
}
执行 onCreateView()
时,会发生几件事:
- 本地
var hereIwantTheObject
被声明并用 null
初始化
LiveData<Resource<ObjectIwant>>
对象的观察者已注册
- 局部变量的值仍然是
null
,但你保证在写入Logcat 时它不是null
- 所以此时您的应用程序将崩溃...
但为什么 hereIwantTheObject 仍然是 null
?这是因为任何 LiveData
对象的观察结果只能在当前函数 onCreateView()
执行完成后进入 UI 线程。
此时局部变量将被丢弃,因此如果您希望稍后能够为其赋值,则需要将其设为 属性:
private var hereIwantTheObject: String? = null
现在,如果您删除带有 hereIwantTheObject 的局部声明的行,并将 Log.i(...)
语句移动到如果 [=] 发生更改时执行的块19=] 对象,一切都会如愿以偿
response.data?.let { brastlewarkTown ->
hereIwantTheObject = brastlewarkTown
Log.i(TAG, "onCreateView: ${hereIwantTheObject!!.name}")
}
我正在尝试在我的 HomeFragment 中从 MutableLiveData<Resource<ObjectIWant>>
获取一个对象到 var hereIwantTheObject : ObjectIWant
,如果您使用协程和 LiveData,显然使用资源 class 是推荐的方法。问题是我希望这个对象在我的变量上并与 MutableLiveData 分离,当我尝试它时它说变量尚未初始化。这是我的 classes 和我尝试过的
ViewModel class:
class HomeFragmentViewModel : ViewModel() {
val mutableVar: MutableLiveData<Resource<ObjectIwant>> = MutableLiveData()
init {
getObjectIwantData()
}
fun getObjectIwantData() = viewModelScope.launch {
mutableVar.postValue(Resource.Loading())
val response = AppRepository().getObjectIwantDataInRepository()
mutableVar.postValue(handleResponse(response))
}
private fun handleResponse(response: Response<ObjectIwant>): Resource<ObjectIwant> {
if (response.isSuccessful) {
response.body()?.let { resultResponse ->
return Resource.Success(resultResponse)
}
}
return Resource.Error(response.message())
}
HomeFragment class 以及我试图获取信息的位置:
class HomeFragment : Fragment() {
lateinit var viewModel: HomeFragmentViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
viewModel = ViewModelProvider(this).get(HomeFragmentViewModel::class.java)
binding.lifecycleOwner = this
var hereIwantTheObject: ObjectIwant? = null
viewModel.brastlewarkTownData.observe(viewLifecycleOwner, Observer { response ->
response.data?.let { brastlewarkTown ->
hereIwantTheObject = brastlewarkTown
}
})
Log.i(TAG, "onCreateView: ${hereIwantTheObject!!.name")
return binding.root
}
}
这里是资源 class:
sealed class Resource<T>(
val data: T? = null,
val message: String? = null
) {
class Success<T>(data: T) : Resource<T>(data)
class Error<T>(message: String, data: T? = null) : Resource<T>(data, message)
class Loading<T> : Resource<T>()
}
执行 onCreateView()
时,会发生几件事:
- 本地
var hereIwantTheObject
被声明并用null
初始化
LiveData<Resource<ObjectIwant>>
对象的观察者已注册- 局部变量的值仍然是
null
,但你保证在写入Logcat 时它不是 - 所以此时您的应用程序将崩溃...
null
但为什么 hereIwantTheObject 仍然是 null
?这是因为任何 LiveData
对象的观察结果只能在当前函数 onCreateView()
执行完成后进入 UI 线程。
此时局部变量将被丢弃,因此如果您希望稍后能够为其赋值,则需要将其设为 属性:
private var hereIwantTheObject: String? = null
现在,如果您删除带有 hereIwantTheObject 的局部声明的行,并将 Log.i(...)
语句移动到如果 [=] 发生更改时执行的块19=] 对象,一切都会如愿以偿
response.data?.let { brastlewarkTown ->
hereIwantTheObject = brastlewarkTown
Log.i(TAG, "onCreateView: ${hereIwantTheObject!!.name}")
}