Включить тег и привязку данных

Я хочу использовать один из моих макетов несколько раз в одном и том же виде, используя include. Допустим, у меня есть custom.xml, включая несколько TextView.

custom.xml:

 <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Я несколько раз включал этот макет в parent.xml:

 <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <include layout="@layout/custom"
        android:id="@+id/layout1"/>

    <include layout="@layout/custom"
        android:id="@+id/layout2"/>
</LinearLayout>

Теперь я хочу привязать свои модели данных к этому макету, но проблема в том, что я не знаю, как привязать две разные модели данных к layout1 и layout2, поскольку обе они ссылаются на один макет, который равен custom.xml. Насколько я знаю, я могу добавить этот тег в свой макет xml:

    <data>
       <variable name="user" type="com.myproject.model.User"/>
   </data>

Но мне нужно привязать две разные модели данных к custom.xml.

Мой вопрос в том, как иметь включенный макет несколько раз в одном представлении и передавать им разные данные с помощью привязки данных? что-то вроде передачи данных в макет, но не статической привязки модели к xml.

Я также нашел этот вопрос, в котором точно такая же проблема Но поскольку привязка данных выпущена в более новых версиях Android, я ищу способ решить ту же проблему с помощью привязки данных. Вот часть вопроса, которую я процитировал для пояснения:

Например, у меня есть тщательно продуманный макет, который я хочу отобразить в своем представлении три раза. Для каждого из этих экземпляров потребуются разные значения. Поскольку include - это, по сути, взять этот XML и вставить его сюда, мне понадобится что-то более мощное.


person Milad Faridnia    schedule 05.10.2016    source источник
comment
Если макеты такие же, и меняются только данные, почему бы вам не подумать об использовании настраиваемого recycleView?   -  person Alex Chengalan    schedule 05.10.2016
comment
потому что я хочу передать две разные модели данных, например, одна - User, а другая - Address, но обе модели используют один и тот же макет для отображения своих данных.   -  person Milad Faridnia    schedule 05.10.2016
comment
@MiladFaridnia Привет, джентльмен, не могли бы вы помочь мне с заданным комментарием к вопросу ссылки? stackoverflow.com/questions/35554796/   -  person Kevan Aghera    schedule 06.04.2018


Ответы (3)


Вы можете передать это от parent.xml

<include layout="@layout/custom"
    android:id="@+id/layout1"
    app:user="@{object of user1`}"/>

<include layout="@layout/custom"
    android:id="@+id/layout2"
    app:user="@{object of user2`}"/>

Здесь нужно передать User объект из parent.xml

Убедитесь, что у вас есть <data> в custom.xml

<data>
   <variable name="user" type="com.myproject.model.User"/>
</data>

Здесь есть подробный ответ по этому поводу, обратитесь к нему

person Ravi    schedule 05.10.2016
comment
Спасибо за ваш ответ. Это так близко к окончательному ответу, но можно ли передать два типа моделей (например, один - это пользователь, а другой - адрес) в custom.xml? - person Milad Faridnia; 05.10.2016
comment
да, в этом случае вам нужно взять две переменные в custom.xml - person Ravi; 05.10.2016
comment
что-то вроде этого ? ‹Data› ‹имя переменной = тип пользователя = com.myproject.model.User /› ‹имя переменной = тип адреса = com.myproject.model.Address /› ‹/data› - person Milad Faridnia; 05.10.2016
comment
Сначала мне было интересно, почему это должно работать, потому что я не определил привязку для app:user. НО это работает как шарм! Благодарность - person m.zander; 15.12.2017
comment
что, если я хочу передать два параметра, это не сработает - person CodingTT; 17.10.2018
comment
Вы можете передать 2 параметра. - person RatneZ; 27.12.2019
comment
Он должен быть привязан: пользователь вместо приложения: пользователь developer.android. ru / topic / libraries / data-binding / - person Wamiq; 18.11.2020

Мы знаем, как использовать имя POJO и его тип в XML, который мы используем в setContentView() в качестве родительского представления. Нам следует сосредоточиться на теге include, если мы включаем какие-либо макеты из ресурса следующим образом:

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

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

    <data>

        <variable
            name="user"
            type="exapmpe.model.User" />
    </data>

    <android.support.design.widget.CoordinatorLayout
        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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </android.support.design.widget.AppBarLayout>

        <include
            layout="@layout/content_main"
            bind:user="@{user}" />

    </android.support.design.widget.CoordinatorLayout>

</layout>

Здесь мы использовали атрибут bind, чтобы передать объект, чтобы показать подробную информацию на экране содержимого. Убедитесь, что имя объекта должно совпадать в обоих местах, например bind:user="@{user}. content_main.xml должен выглядеть следующим образом:

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

<layout>

    <data>

        <variable
            name="user"
            type="exapmpe.model.User" />
    </data>

    <RelativeLayout 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"
        android:id="@+id/content_main" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.firstName + user.lastName}" />

    </RelativeLayout>

</layout>
person Deva    schedule 02.01.2017

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

person Lior    schedule 05.10.2016
comment
Спасибо за полезную ссылку, но я думаю, вы должны включить в свой ответ больше описания - person Milad Faridnia; 05.10.2016