Синтетическое расширение Kotlin и несколько включают в себя одну и ту же компоновку

Как получить доступ к просмотру с использованием синтетического расширения kotlin, если у меня есть макет, как показано ниже:

Файл: two_days_view.xml

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

    <include
        android:id="@+id/day1"
        layout="@layout/day_row"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <include
        android:id="@+id/day2"
        layout="@layout/day_row"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

file: day_row.xml

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

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

    </LinearLayout>

Как получить доступ к dayName? Я искал несколько таких:

day1.dayName.text = "xxx"
day2.dayName.text = "sss"

Я вижу в Studio, что у меня есть доступ к dayName, но к которому относится один из dayName TextView?

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

конечно, я всегда могу:

day1.findViewById(R.id.dayName).text = "xxx"

но я ищу хорошее решение.:)

Ответ 1

Как общее правило, вы не должны создавать макеты, которые в конечном итоге имеют несколько представлений с одним и тем же идентификатором - именно по этой причине.

Но, чтобы решить вашу проблему: Вместо импорта

kotlinx.android.synthetic.main.layout.day_row.*

вы можете импортировать

kotlinx.android.synthetic.main.layout.day_row.view.* (Обратите внимание на добавочный .view в конце).

Это импортирует представления не как свойства на уровне Activity/Fragment, а в качестве свойств расширения для View. Таким образом, вы можете сделать это так, как хотите, считая, что day1 и day2 содержат нужные вам виды:

day1.dayName.text = "xxx"
day2.dayName.text = "sss"

Ответ 2

У меня был тот же случай. Именно так я сделал это:

Макет в моей активности/фрагменте:

    <include
        android:id="@+id/field1"
        layout="@layout/merge_field"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <include
        android:id="@+id/field2"
        layout="@layout/merge_field"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Макет: merge_field.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mergeContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">

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

</FrameLayout>

Код Котлина:

val tv_title = field1?.findViewById(R.id.tv_title)
tv_title.text = "This way it works"

Обратите внимание на корневой вид <FrameLayout>. Это только работало для меня таким образом.

Использование тега <merge> не работает

Ответ 4

В этом случае используйте:

(day1 as TextView).text = ""
(day2 as TextView).text = ""