在“我的视图”模型中创建内部实时数据观察器并将其与数据绑定连接时,我遇到了一个问题。现在,我的代码的一部分看起来像这样: 片段:
SearchFragment类:Fragment(),可注入{
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
@Inject lateinit var searchViewModel: SearchViewModel
private lateinit var disposable: Disposable
private var searchView: SearchView? = null
private var adapter: SearchCityListAdapter? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding: SearchFragmentBinding = DataBindingUtil.inflate(inflater, R.layout.search_fragment, container, false)
binding.apply { viewModel = searchViewModel
setLifecycleOwner(this@SearchFragment)}
setHasOptionsMenu(true)
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
searchViewModel = ViewModelProviders.of(this, viewModelFactory).get(SearchViewModel::class.java)
submitViewModel()
}
private fun submitViewModel(){
viewModel.searchCityList.observe(this, Observer {it ->
if (adapter == null){
it?.let { adapter = SearchCityListAdapter(it)}.also {createAdapter()}
} else {
it?.let { adapter!!.updateList(it) }.also { adapter!!.notifyDataSetChanged() }
}
})
viewModel.responseStatus.observe(this, Observer {
it?.let { it ->
when(it.status){
Status.SUCCESS -> progressBar.visibility = View.INVISIBLE
Status.FAILURE -> progressBar.visibility = View.INVISIBLE
Status.ERROR -> progressBar.visibility = View.INVISIBLE
Status.LOADING ->progressBar.visibility = View.VISIBLE
} }
})
}
ViewModel:
class SearchViewModel @Inject constructor(val haloApplication: HaloApplication): ViewModel() {
val progressBarVisibility: MediatorLiveData<Boolean> = MediatorLiveData()
private val responseStatus: MutableLiveData<Response> = MutableLiveData()
val searchCityList: MutableLiveData<SearchCityList> = MutableLiveData()
fun searchCity(cityName: String){
haloApplication.networkRepository.fetchCityList(cityName, responseStatus, searchCityList)
}
init {
progressBarVisibility.value = false
progressBarVisibility.addSource(responseStatus){
it?.let { when(it.status) {
Status.FAILURE -> progressBarVisibility.value = false
Status.ERROR -> progressBarVisibility.value = false
Status.SUCCESS -> progressBarVisibility.value = false
Status.LOADING -> progressBarVisibility.value = true
} }
}
}
}
XML布局文件:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.mbojec.halo.viewmodel.SearchViewModel"/>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.SearchFragment">
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:layout_gravity="center"
android:visibility="@{viewModel.progressBarVisibility, default=invisible}"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/searchCityListRecycleView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
</layout>
DataBinder文件:
import android.view.View
import androidx.databinding.BindingAdapter
@BindingAdapter("android:visibility")
fun setVisibility(view: View, value: Boolean) {
view.visibility = if (value) View.VISIBLE else View.INVISIBLE
}
由于某些未知原因,Fragment部分工作正常,但是当responseStatus中发生更改并且通过数据绑定的连接无效时,viewmodel部分永远不会触发。这不是我第一次创建视图模型或转换模型,但这是我第一次遇到这样的问题。我尝试了十几种情况,每次结果都是一样的。首先,我指责新的AndroidX库,但是他们从github上获得的Sunflower示例也可以正常工作,所以我暂时不知道这一点。
答案 0 :(得分:0)
MediatorLiveData
仅在观察addSource
本身时才开始观察通过MediatorLiveData
添加的源。由于没有观察到progressBarVisibility
,因此您不会收到任何回调。
答案 1 :(得分:0)
您必须观察progressBarVisibility才能接收onChanged回调。 (每个可观察的对象都需要一个观察对象才能使用)
让我们进行一些更改:
progressBarVisibility
不必是MediatorLiveData; responseStatus
并遵守它; progressBarVisibility
添加responseStatus
作为来源。internal val progressBarVisibility: LiveData<Boolean> = Transformations.map(responseStatus) {
when (it.status) {
Status.LOADING -> true
Status.ERROR, Status.SUCCESS, Status.FAILURE -> false
}
}
现在,您可以观察progressBarVisibility
并接收回调。