Когда выражение оценивается в Android привязке данных? - PullRequest
0 голосов
/ 17 июня 2020

С помощью структуры привязки данных Android, я понимаю, что вы можете передать объект, который расширяет baseObservable на макет xml, использовать @Bindable в геттерах и сделать notifyPropertyChanged(BR.xxx) для повторного выполнения связанной части.

Я не понимаю следующего: если вы не используете большую часть вышеперечисленного и просто вызываете геттер непосредственно в xml, когда он будет оцениваться?


Вот код:

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 - это «связываемое» поле, а notifyPropertyChanged(BR.a) вызывается в otherVariable, тогда someViewModel.getName() также будет переоценен, а testView будет отражать последнее значение видимости, верно?

  5. Вдобавок, если я повторно установил someViewModel, вызвав binding.setSomeViewModel(), но передаю ТО ЖЕ someViewModel экземпляр, сделает ли это что-нибудь? Будет ли выражение повторно вычислено?

Ответы [ 2 ]

0 голосов
/ 17 июня 2020

Я предлагаю вам создать настраиваемый адаптер привязки для изменяемой видимости и использовать 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 и добавьте в него следующую функцию:

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}" />
0 голосов
/ 17 июня 2020

Если someViewModel.name когда-либо изменяется, обновляется ли видимость testView?

Это зависит от базовой технологии, которую вы используете. LiveData? Да, BaseObservable необходимо вручную уведомить об изменении наблюдаемого свойства.

Когда выполняется оценка someViewModel.getName () или как часто?

LiveData? когда вы устанавливаете / публикуете значение. BaseObservable, когда вы его уведомляете

То же, что и точка 2

Если вы измените базовое значение и должным образом уведомите об этом изменении, оно будет распространено соответствующим образом. Если вы измените экземпляр наблюдаемого объекта, этого не произойдет.

...