繁体   English   中英

何时在 Android 数据绑定中评估表达式?

[英]When does expression get evaluated in Android Data-binding?

使用 Android 数据绑定框架,我知道您可以传递一个 object 将baseObservable扩展为布局 xml,在 getter 上使用@Bindable相关部分并进行notifyPropertyChanged(BR.xxx)

我不明白的是:如果你不使用上面的大部分东西,只是直接在 xml 中调用 getter,什么时候会评估它?


这是代码:

my_widget.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="someViewModel"
            type="com.example.SomeViewModel" />
    </data>

    <androidx.cardview.widget.CardView>
        <View
            android:id="@+id/testView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="@{someViewModel.getName() ? View.VISIBLE : View.GONE}" />
    </androidx.cardview.widget.CardView>
</layout>

MyView.java

MyWidgetBinding binding = MyWidgetBinding.inflate(LayoutInflater.from(mContext), parent, false);
binding.setSomeViewModel(someViewModel);

问题:

  1. 如果someViewModel.name发生变化, testView的可见性会刷新吗?

  2. someViewModel.getName()什么时候评估或多久评估一次?

  3. 如果表达式更复杂,例如: android:visibility="@{func(otherVariable, someViewModel.getName())? View.VISIBLE: View.GONE}" ,说otherVariable是上面数据部分中定义的另一个变量,如果不知何故otherVariable被重新设置,然后someViewModel.getName()将被评估并且testView将反映最新的可见性值,对吗?

  4. 跟进问题 3,如果otherVariable更改为otherVariable.a ,其中a是“可绑定”字段,并且在 otherVariable 中调用notifyPropertyChanged(BR.a) otherVariable那么someViewModel.getName()也将重新评估,并且testView将反映最新的能见度值,对吗?

  5. 此外,如果我通过调用 binding.setSomeViewModel binding.setSomeViewModel()重新设置someViewModel但传入相同的someViewModel实例,它会做任何事情吗? 表达式会被重新评估吗?

如果 someViewModel.name 发生变化,testView 的可见性会刷新吗?

这取决于您使用的底层技术。 实时数据? 是的 BaseObservable 您必须手动通知观察到的属性已更改。

someViewModel.getName() 什么时候评估或多久评估一次?

实时数据? 当您设置/发布一个值时。 BaseObservable 当你通知它时

  1. 与第 2 点相同

  2. 如果您更改基础值并正确通知此更改,它将相应地传播。 如果您更改观察到的 object 的实例,则不会。

我建议您为可变可见性创建自定义绑定适配器并使用 LiveData 来更新可见性。

代码:

@BindingAdapter("mutableVisibility")
fun setMutableVisibility(view: View, visibility: MutableLiveData<Boolean>) {
    val parentActivity: AppCompatActivity? = view.getParentActivity()
    if (parentActivity != null) {
        visibility.observe(
                parentActivity,
                Observer { value -> if (value) view.visibility = View.VISIBLE
                else view.visibility = View.GONE})
    }
}

要获取父活动,请创建 ActivityExtensions.kt 文件并在其中添加以下 function:

fun View.getParentActivity(): AppCompatActivity?{
    var context = this.context
    while (context is ContextWrapper) {
        if (context is AppCompatActivity) {
            return context
        }
        context = context.baseContext
    }
    return null
}

在 ViewModel 中:

//Other code here...
val itemVisibility = MutableLiveData<Boolean>()
//Other logic here to init itemVisible
if(itemVisibile) itemVisibility.value = true else itemVisibility.value = false

最后是layoutItem:

<View
     android:id="@+id/testView"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     app:mutableVisibility ="@{viewModel.itemVisibility}" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM