Kotlin synthetic extension and several include same layout

孤者浪人 提交于 2020-01-01 04:28:04

问题


How to access to view using kotlin synthetic extension if I have a layout like below:

file: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>

How to access to dayName? I looked for some like this:

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

I see in Studio that I have access to dayName but to which one of dayName TextView is reference to?

Normal if I have only one included layout it works fine. But now I have multiple times included same layout.

of course I can always do:

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

but I'm looking for nice solution. :)


回答1:


As a general rule of thumb, you should not construct layouts that end up having multiple views with the same id - for this very reason.

But, to solve your problem: Instead of importing

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

you can import

kotlinx.android.synthetic.main.layout.day_row.view.* (Notice the additional .view at the end).

This will import the views not as properties on the Activity/Fragment level, but instead as extension properties for View. That way, you can do it the way you want, assuming that day1 and day2 contain the views you want:

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



回答2:


I had the same case. This is the way I made it work:

Layout in my activity / fragment:

    <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" />

Layout: 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>

Kotlin code:

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

Note the <FrameLayout> root view. It only worked for me this way.

Using a <merge> tag it did not work




回答3:


In this case, use:

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


来源:https://stackoverflow.com/questions/42435227/kotlin-synthetic-extension-and-several-include-same-layout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!