如何将信息从 MutableLiveData<Resource<Object>> 提取到视图中更简单的对象模型中



我试图在我的HomeFragment中从MutableLiveData<Resource<ObjectIWant>>var hereIwantTheObject : ObjectIWant获得对象,显然使用资源类是推荐的方法,如果您使用协程和LiveData。问题是,我希望这个对象在我的变量上并从mutableelvedata中分离出来,当我尝试的时候它说变量还没有初始化。这里是我的课程和我所尝试的

ViewModel类:

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 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
}
}

这里是Resource类:

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 hereIwantTheObjectnull
  • 声明和初始化
  • 注册LiveData<Resource<ObjectIwant>>对象的观察者
  • 本地变量的值仍然是null,但是当写入Logcat
  • 时,您承诺它不是null
  • 所以此时你的应用程序会崩溃…

但是为什么hereIwantTheObject仍然是null?这是因为任何LiveData对象的观察结果只能在当前函数onCreateView()执行完成后才能进入UI线程。

此时,局部变量将被丢弃,所以如果你想以后能够给它赋值,你需要把它变成一个属性:

private var hereIwantTheObject: String? = null

现在,如果您删除带有hereIwantTheObject局部声明的行,并将Log.i(...)语句移动到LiveData对象发生更改时执行的块中,则一切都将按预期工作

response.data?.let { brastlewarkTown ->
hereIwantTheObject = brastlewarkTown
Log.i(TAG, "onCreateView: ${hereIwantTheObject!!.name}")
}

相关内容

  • 没有找到相关文章

最新更新