Привязка данных через интерфейс - PullRequest
0 голосов
/ 05 октября 2018

У меня есть простая установка привязки данных:

Моя ViewModel:

public class MyViewModel {

    public ObservableField<Integer> viewVisibility = new ObservableField<>(View.VISIBLE);

    public void buttonClicked() {
        if (viewVisibility.get() == View.GONE) {
            viewVisibility.set(View.VISIBLE);
        } else {
            viewVisibility.set(View.GONE);
        }
    }
}

и макет:

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
            name="viewModel"
            type="com.example.fweigl.playground.MyViewModel" />

    </data>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="64dp">

        <View
            android:visibility="@{viewModel.viewVisibility}"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:background="#00ff00" />

        <Button
            android:text="click me"
            android:onClick="@{() -> viewModel.buttonClicked()}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>
</layout>

Как вы можете видеть, каждый щелчок наКнопка переключает ObservableField<Integer> viewVisibility на модель просмотра, которая, в свою очередь, переключает видимость зеленого прямоугольника. Это прекрасно работает.

Теперь я хочу сделать то же самое, но с использованием интерфейса в качестве модели представления:

public interface IMyViewModel {

    public void buttonClicked();

    public ObservableField<Integer> viewVisibility = new ObservableField<>(View.VISIBLE);

}

модель представления:

public class MyViewModel implements IMyViewModel {
    @Override
    public void buttonClicked() {
        if (viewVisibility.get() == View.GONE) {
            viewVisibility.set(View.VISIBLE);
        } else {
            viewVisibility.set(View.GONE);
        }
    }
}

и в макете я импортирую интерфейс вместо реализации:

<data>

    <variable
        name="viewModel"
        type="com.example.fweigl.playground.IMyViewModel" />

</data>

Что работает, так это привязка для нажатия кнопки, вызывается buttonClicked и значениеviewVisibility изменено.

Что не работает - это изменение видимости зеленого прямоугольника.Изменения значения viewVisibility не отражаются в макете.

Я что-то не так делаю или привязка данных не (полностью) не работает с интерфейсами как моделями представления?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Для привязки данных требуется получить и установить, чтобы сделать работу, он не имеет прямого доступа к вашему полю.Так что это также не будет работать без установщика геттера

public class MyViewModel {

    public ObservableField<Integer> viewVisibility = new ObservableField<>(View.VISIBLE);

    public void buttonClicked() {
        if (viewVisibility.get() == View.GONE) {
            viewVisibility.set(View.VISIBLE);
        } else {
            viewVisibility.set(View.GONE);
        }
    }
}

Так как интерфейс не имеет установщика геттера, поэтому их нельзя использовать в качестве модели.

0 голосов
/ 05 октября 2018

Если бы вы обернули любую переменную, которую хотите связать с вашим представлением, в LiveData <>, Android автоматически распакует данные и свяжет их с представлением

...