数据绑定:在点击时通过 LiveData 变量调整可见性

chr*_*rjs 9 android android-databinding

我想ProgressBar根据MutableLiveData我的ViewModel. 我知道这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
}
Run Code Online (Sandbox Code Playgroud)

查看型号:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

布局:

<?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>
Run Code Online (Sandbox Code Playgroud)

绑定适配器:

@Suppress("unused")
object BindingAdapters {
    @BindingAdapter("goneUnless")
    @JvmStatic
    fun goneUnless(view: View, visible: Boolean) {
        view.visibility = if (visible) View.VISIBLE else View.GONE
    }
}
Run Code Online (Sandbox Code Playgroud)

当我点击ButtonTimber通话作品,但负载指示的知名度并没有改变(从GONEVISIBLE)。我该如何解决这个问题,也许摆脱这两个变量而只有一个?

谢谢。

Dro*_*man 14

你实际上并不需要 a BindingAdapter,有一种更简单的方法来完成你想要的。

1)ViewModel:将您的加载字段更改为:val isLoading = ObservableBoolean()OR 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}"/>
Run Code Online (Sandbox Code Playgroud)

使用set(value)改变的值ObservableBoolean或者setValue()postValue()如果你关闭主线程)的LiveData

*公开LiveData实例并保持实际MutableLiveData私有被认为是一种很好的做法。

  • @ThiệnKopites,您必须在布局文件的 &lt;data&gt; 块内添加 `&lt;import type="android.view.View"/&gt;` (4认同)