簡體   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