Двусторонняя привязка данных для Android: включен атрибут

Я пытаюсь выяснить библиотеку двусторонней привязки данных в Android. Я хочу включить / отключить LinearLayout (и RelativeLayout внутри), изменив атрибут android:enabled в xml.

Часть XML выглядит так:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:layout_margin="5dp"
    android:gravity="center"
    android:enabled="@={viewModel.asd}"
    ndroid:onClick="@{()-> viewModel.doSomething()}"
    android:background="@drawable/shortcut_button_label_selector"
    android:orientation="horizontal">

    <RelativeLayout
        android:layout_width="40dp"
        android:layout_height="match_parent"
        android:enabled="@={viewModel.asd}"
        android:background="@drawable/shortcut_button_icon_selector">

Теперь я хочу сделать это потому, что эти два селектора (shortcut_button_label_selector и shortcut_button_icon_selector) выглядят так:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:state_enabled="false"
        android:drawable="@color/grey_300"></item>
    <item
        android:state_enabled="true"
        android:drawable="@color/menubar_background"></item>

</selector>

Я хочу иметь возможность динамически изменять фон на основе включенного атрибута в представлении. Причина, по которой я выбрал атрибут enabled, заключается в том, что я получил событие onClick для этого LinearLayout, и мне нужно отключить его (делая его неактивным); У меня была такая же проблема с атрибутом android:clickable.

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

java.lang.RuntimeException: обнаружены ошибки привязки данных. ****/ ошибка привязки данных ****msg: не удается найти метод получения атрибута 'android:enabled' с типом значения boolean для android.widget.LinearLayout.

ViewModel.asd - это просто public boolean / ObservableBoolean, я пробовал оба.

Может кто-нибудь объяснить, что происходит и почему я получаю ошибку? Я вижу методы isEnabled / setEnabled в классе View (которые расширяют Layouts).

Есть ли способ, которым я могу двигаться дальше с моим подходом, или я должен изменить его полностью?

// РЕДАКТИРОВАТЬ: мне может не понадобиться двусторонняя привязка.. Я больше не знаю // РЕДАКТИРОВАТЬ продолжение: Возможно, придется что-то делать с моим наследованием ViewModel:

Файл макета имеет viewModel типа abMainViewModel, но поле asd находится в abBaseViewModel (MainViewModel расширяет BaseViewModel). Теперь мне бы хотелось, чтобы я обновил поле asd из любого другого представления, расширяющего BaseViewModel, и он автоматически обновил бы включенный атрибут.

Это также не работает со строками.. Я думаю, что это наследование

С уважением, Марчин

2 ответа

Там может быть несколько причин вашей ошибки. Во-первых, двусторонняя привязка данных не работает с android:enabled приписывать. Это связано с тем, что отсутствует обратный вызов, сообщающий привязке данных об изменении свойства.

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

Другая причина, по которой вы можете получить такую ​​ошибку, заключается в том, что модель может не иметь привязываемого свойства. Вы должны использовать либо Observable:

public class ViewModel extends BaseObservable {
    private boolean asd = true;

    @Bindable
    public boolean getAsd() { return asd; }

    public void setAsd(boolean asd) {
        this.asd = asd;
        notifyPropertyChanged(this, BR.asd);
    }
}

или используйте ObservableFields:

public class ViewModel {
    public final ObservableBoolean asd = new ObservableField(true);
}

Без этого одностороннее связывание данных будет работать только в первый раз - если вы измените ViewModel, пользовательский интерфейс не будет обновляться.

Не похоже, что вам нужно двустороннее связывание данных для android:enabled приписывать. Односторонние данные должны работать нормально, чтобы изменить состояние селектора.

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

По сути, у меня есть привязка к основному действию (называемая MainActivity) и отдельные привязки для фрагментов, заменяемых внутри этого действия. Обе связанные модели представления расширяют BaseViewModel, которая содержит это логическое значение. Привязка основной активности должна обновляться при каждом обновлении фрагмента (скажем, я должен что-то скрывать / показывать в зависимости от того фрагмента, на котором я на самом деле).

Теперь, что я ожидал, это то, что, если бы я установил логическое значение в MainActivityViewModel (это фактически установило бы значение в базовом классе и заменило бы поле "это" в другом ViewModel, расширяющем базу, которую обновил бы первый... Глупый я, Я понял, что должен обновить логическое значение в MainViewModel напрямую, это базовая концепция Java и не имеет ничего общего с Android..

Одна вещь, которую я не знаю, как объяснить, это то, что это логическое значение должно быть возвращено из метода java.util.Set # Содержит. У меня есть ObservableField observableSet (в MainViewModel сейчас) и метод isInTheSet(Object), возвращающий set.contains (Object).

Когда я выполнил метод в файле XML (viewModel.isInTheSet(Object)), он не обновил представление, когда я изменил значение ObservableField. Однако, когда я изменил XML для использования viewModel.observableSet.contains(Object), это сработало. Кто-нибудь может объяснить это?

Извините за то, что создала массу путаницы, у меня вчера был длинный рабочий день.

// РЕДАКТИРОВАТЬ: И да, мне не нужно двустороннее связывание..

Marcin

Другие вопросы по тегам