我想根据ViewModel
中的MutableLiveData
变量调整ProgressBar
的可见性。我了解到MutableLiveData
不起作用,所以我需要一个LiveData
变量来转换它......有点奇怪,但至少它应该工作对吗?
好吧,它目前不起作用。我不明白为什么我想要两个变量来做一件事。
我希望代码不言自明:
活动:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityLoginBinding = DataBindingUtil.setContentView(this, R.layout.activity_login)
binding.lifecycleOwner = this
binding.viewmodel = vm
}
查看模型:
class LoginViewModel : ViewModel() {
var isLoading: MutableLiveData<Boolean> = MutableLiveData(false)
var showLoadingIndicator: LiveData<Boolean> = Transformations.map(isLoading) { isLoading.value }
fun login() {
Timber.d("login")
isLoading.value = true
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewmodel"
type="mypackage.LoginViewModel"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.button.MaterialButton
android:onClick="@{() -> viewmodel.login()}"/>
<include
layout="@layout/loading_indicator"
app:goneUnless="@{viewmodel.showLoadingIndicator}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
绑定适配器:
@Suppress("unused")
object BindingAdapters {
@BindingAdapter("goneUnless")
@JvmStatic
fun goneUnless(view: View, visible: Boolean) {
view.visibility = if (visible) View.VISIBLE else View.GONE
}
}
当我单击Button
时,Timber
调用有效,但加载指示器的可见性没有改变(从GONE
到VISIBLE
)。我如何解决这个问题,也许摆脱两个变量并且只有一个变量?
谢谢。
你实际上不需要BindingAdapter
,有一种更简单的方法来完成你想要的。
1) 视图模型:将加载字段更改为:val isLoading = ObservableBoolean()
或val isLoading = MutableLiveData<Boolean>
*
2) 在布局的<data>
标签中添加导入:<import type="android.view.View"/>
3)您的包含将成为:
<include
layout="@layout/loading_indicator"
android:visibility="@{viewmodel.isLoading ? View.VISIBLE : View.GONE}"/>
使用 set(value)
更改 LiveData
的ObservableBoolean
或setValue()
的值(如果您不在主线程中,则postValue()
)。
*公开LiveData
实例并保持实际MutableLiveData
的私密性被认为是一种很好的做法。
这对我来说非常有用:
@BindingAdapter("android:visibility")
fun View.setVisibility(visible: Boolean?) {
visibility = if (visible != null && visible) View.VISIBLE else View.GONE
}