Синтетическое расширение 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>
не работает
Ответ 3
"Опасность использования kotlin.syntetic для блока в макете" https://link.medium.com/rMwau5VAZT
Ответ 4
В этом случае используйте:
(day1 as TextView).text = ""
(day2 as TextView).text = ""