DataBinding:通过单击时的 LiveData 变量调整可见性
DataBinding: Adjust visibility by LiveData Variable on Click
我想根据 ViewModel
中的 MutableLiveData
变量调整 ProgressBar
的可见性。我了解到 MutableLiveData
不起作用,所以我需要一个 LiveData
变量来转换它...有点奇怪,但至少它应该起作用吧?
好吧,目前它不起作用。而且我不明白为什么我要两个变量做一件事。
我希望代码不言自明:
Activity:
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) ViewModel:将您的加载字段更改为: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)
更改 ObservableBoolean
或 setValue()
的值(postValue()
如果您不在主线程中) LiveData
。
*公开 LiveData
实例并保持实际 MutableLiveData
私有被认为是一种好的做法。
这对我来说非常有用:
@BindingAdapter("android:visibility")
fun View.setVisibility(visible: Boolean?) {
visibility = if (visible != null && visible) View.VISIBLE else View.GONE
}
我想根据 ViewModel
中的 MutableLiveData
变量调整 ProgressBar
的可见性。我了解到 MutableLiveData
不起作用,所以我需要一个 LiveData
变量来转换它...有点奇怪,但至少它应该起作用吧?
好吧,目前它不起作用。而且我不明白为什么我要两个变量做一件事。
我希望代码不言自明:
Activity:
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) ViewModel:将您的加载字段更改为: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)
更改 ObservableBoolean
或 setValue()
的值(postValue()
如果您不在主线程中) LiveData
。
*公开 LiveData
实例并保持实际 MutableLiveData
私有被认为是一种好的做法。
这对我来说非常有用:
@BindingAdapter("android:visibility")
fun View.setVisibility(visible: Boolean?) {
visibility = if (visible != null && visible) View.VISIBLE else View.GONE
}