Привязка данных: доступ к полям во включенном макете - макет приведен к просмотру - PullRequest
4 голосов
/ 26 сентября 2019

Я использую привязку данных в своем проекте, и она работает, как ожидалось.Теперь я хотел бы использовать тег <include> и поля доступа во включенном макете, и я не могу заставить его работать.

Я попробовал фрагмент кода, который я нашел несколько раз в Интернетеэто следующее:

hello_world.xml

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

        <TextView
                android:id="@+id/hello"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        <include
                android:id="@+id/included"
                layout="@layout/included_layout"/>
    </LinearLayout>
</layout>

includes_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/world"/>
</layout>
HelloWorldBinding binding =
    HelloWorldBinding.inflate(getLayoutInflater());
binding.hello.setText("Hello");
binding.included.world.setText("World");

И этот код не работает.Когда я смотрю в Android Studio, binding.included - это вид, и поэтому нет доступа к полям.

binding.hello.setText("Hello"); Работает правильно, поэтому привязка данных работает, по крайней мере, на каком-то уровне.

Как я могу получить доступ к полям во включенном макете?

Ответы [ 3 ]

0 голосов
/ 26 сентября 2019

Оберните ваш включенный макет (includes_layout.xml) внутри ViewGroup.Это решило бы проблему.included_layout.xml должно выглядеть следующим образом:

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

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

 </RelativeLayout>

</layout>

Поэтому, когда вы хотите установить TextView для вашего TextView, вы можете сделать что-то вроде этого:

binding.included.world.setText("World");

Сводка:

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

Надеюсь, это поможет.Веселого кодирования!

0 голосов
/ 26 сентября 2019

Только убедитесь, что не установлен id на include и на включенном макете (оба должны иметь только один id).Для этого включенного макета может потребоваться узел <data />, который может быть пустым (если не передавать переменные из родительского макета, как это делает тот ответ, который я связал выше).

Подобно этому:

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

    <data />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

        <include
            layout="@layout/included_layout"/>

    </LinearLayout>

</layout>

А это:

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

    <data />

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

</layout>
0 голосов
/ 26 сентября 2019

Удалите этот тег макета

includes_layout.xml

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

, затем попробуйте binding.included.world.setText("World")

Более близкий пример

class NavigationActivity : AppCompatActivity() {

private lateinit var activityNavigationBinding:ActivityNavigationBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    activityNavigationBinding = DataBindingUtil.setContentView(
        this,
        R.layout.activity_navigation
    )
    activityNavigationBinding.includeLayout.tv_textView.setText("Sample text")
   }
}

activity_navigation

<?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"
    xmlns:tools="http://schemas.android.com/tools">

<android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">

    <include
            android:id="@+id/includeLayout"
            layout="@layout/app_bar_navigation"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_navigation"
            app:menu="@menu/activity_navigation_drawer" />

</android.support.v4.widget.DrawerLayout>
</layout>

app_bar_navigation

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".activities.NavigationActivity">

  <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/tv_textView"
       />
</android.support.design.widget.CoordinatorLayout>

После этого вам нужно вызывать как bindingObject. (Идентификатор включаемого макета). (Идентификатор представления) .setText или что-либо еще

...