Подтвердить что ты не робот

Привязка данных Android не работает с атрибутами <merge>

Я пытаюсь использовать привязку данных к пользовательским представлениям (возможное использование George Mount показало здесь).

Невозможно представить составные виды без тега <merge>. Однако в этой ситуации завершается привязка данных:

MyCompoundView класс:

public class MyCompoundView extends RelativeLayout {

MyCompoundViewBinding binding;

public MyCompoundView (Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

private void init(Context context){
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    binding = MyCompoundViewBinding.inflate(inflater, this, true);
}

my_compound_view.xml: через app:isGone="@{!data.isViewVisible}" я надеялся контролировать видимость всего составного вида

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

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

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

    <merge
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:isGone="@{!data.isViewVisible}">

        <ImageView
            android:id="@+id/image_image"
            android:layout_width="60dp"
            android:layout_height="60dp"
            app:imageUrl="@{data.imagePhotoUrl}"/>

         <!-- tons of other views-->

    </merge>

</layout>

Ошибки компилятора:

Error:(13) No resource identifier found for attribute 'isGone' in package 'com.example'
Error:(17, 21) No resource type specified (at 'isGone' with value '@{!data.isViewVisible}').

У меня есть все необходимые методы @BindingAdapter. Теперь я наследую представление из FrameLayout и использую <RelativeLayout> вместо <merge> - и он работает. Но у меня есть дополнительный вложенный макет.

Вопрос: merge attrs игнорируются. Есть ли способ обхода этого?

Android Studio 1.5.1 stable

Gradle плагин com.android.tools.build:gradle:1.5.0

4b9b3361

Ответ 1

После инфляции нет объекта слияния, поэтому присваивать значения с помощью тега слияния нечего. Я не могу придумать какой-либо привязывающий тэг, который будет работать на слияние.

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

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

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

    <merge
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <ImageView
            app:isGone="@{!data.isViewVisible}"
            android:id="@+id/image_image"
            android:layout_width="60dp"
            android:layout_height="60dp"
            app:imageUrl="@{data.imagePhotoUrl}"/>
         <!-- tons of other views-->
    </merge>
</layout>

Если вы хотите что-то сделать с классом Binding, вы можете использовать DataBindingUtil для поиска объекта из представления.

@BindingAdapter("isGone")
public static void setGone(View view, boolean isGone) {
    ViewDataBinding binding = DataBindingUtil.findBinding(view);
    //... do what you want with the binding.
}

Ответ 2

Из документации для Android (Библиотека привязки данных: включает в себя)

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

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bind="http://schemas.android.com/apk/res-auto">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <include layout="@layout/name"
           bind:user="@{user}"/>
       <include layout="@layout/contact"
           bind:user="@{user}"/>
   </LinearLayout>
</layout>

Не забудьте передать объект привязки данных в теге <include> (в этом примере: bind:[email protected]{user}) и добавить xmlns:bind="http://schemas.android.com/apk/res-auto" вверху.