using Kotlin 1.20.20 (not that it matters, older versions behaves the same)
When layout is in separate library module Android Studio has no problem finding and refer
Do not import the following library import kotlinx.android.synthetic.main.my_view.view.*
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val view: View = MyView(this)
view.findViewById<TextView>(R.id.textViewPocLib).text = "I can edit the library components"
setContentView(view)
}
class MyView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
LinearLayout(context, attrs, defStyleAttr) {
init {
LayoutInflater.from(context)
.inflate(R.layout.my_view, this, true)
}
}
GL
Sources:
In an incremental improvement on @pablisco's solution above, in my library I have a file:
// SyntheticExports.kt
@file:Suppress("ClassName")
package com.example.library.synthetic.main
import android.view.TextView
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.common_layout.view.rootLayout as syntheticRootLayout
import kotlinx.android.synthetic.main.common_layout.view.retryButton as syntheticRetryButton
object common_layout {
object view {
inline val View.rootLayout: ViewGroup get() = syntheticRootLayout
inline val View.retryButton: TextView get() = syntheticRetryButton
}
}
Then on the other module:
// MainActivity.kt
import com.example.library.synthetic.main.common_layout.view.rootLayout
import com.example.library.synthetic.main.common_layout.view.retryButton
rootView.rootLayout.isVisible = true
rootView.retryButton.setOnClickListener { doIt() }
If this issue is ever fixed, I just need to change imports to start with "kotlinx.android" instead of "comp.example.library".
you could try switching to 1.2.30-eap-16
and adding
androidExtensions {
experimental = true
}
to your build.gradle
.
I also got this issue and my solution is:
Don't use import kotlinx.android.synthetic.main....*
Use findViewById()
For example I changed from
textview_id.text = "abc"
to
findViewById(R.id.textview_id).text = "abc"
As mentioned in the comment by @cesards above this is an on going issue with the Kotlin Android Extentions. And it is not solved as of today.
My primary suggestion is encapsulating the view and the relevant behavior as a custom view and instead of including it via <include>
tag, use it directly in your layout as <com.example.app.YourCustomView>
.
This will work no matter your view class is in another module or not.
However I found a hacky workaround if you only want to get one reference from the included view.
Follow these steps to use kotlin synthetic imports for the layouts included from other modules:
I'm not really sure how and why this works but it's a very fragile and dirty way of reusing layouts.
Your including layout (fragment_example.xml)
<include
android:id="@+id/exampleView"
layout="@layout/example_layout" />
Your included layout (example_layout.xml)
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/exampleView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</merge>
Your fragment class (ExampleFragment.kt)
import kotlinx.android.synthetic.main.fragment_example.exampleView
// Do not import the exampleView through example_layout.exampleView
class ExampleFragment : Fragment() {
// Do something with imported exampleView
}
I solved my issue with copy both androidExtension and buildscript from project build.gradle to module that uses the library.
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath "com.android.tools.build:gradle:$gradle_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
androidExtensions {
experimental = true
}
Note: I use the following version of kotlin and gradle:
buildscript {
ext.kotlin_version = '1.3.0'
ext.gradle_version = '3.0.1'