问题
I am working one project using kotlin + Rxjava + MVVM. During development facing issue of importing view ids in Fragment or viewholder.
import kotlinx.android.synthetic.main.layout.*
unused with kotlin.
Normaly view id should used from kotlin synthetic layout imports but it directly import it from R.id that should not happen.
Kotlin plugin version : org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.40
My gradle file :
apply plugin: 'com.android.feature'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'idea'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 27
baseFeature true
defaultConfig {
minSdkVersion 23
targetSdkVersion 27
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
api "com.android.support:design:$rootProject.support_library_version"
api "com.android.support:appcompat-v7:$rootProject.support_library_version"
api "com.android.support:recyclerview-v7:$rootProject.support_library_version"
api "com.android.support:support-dynamic-animation:$rootProject.support_library_version"
api "com.android.support:cardview-v7:$rootProject.support_library_version"
api "com.android.support:customtabs:$rootProject.support_library_version"
api "com.android.support.constraint:constraint-layout:1.1.0-beta5"
api 'android.arch.lifecycle:extensions:1.1.0'
api 'androidx.core:core-ktx:0.2'
api "com.google.dagger:dagger:$rootProject.dagger_version"
kapt "com.google.dagger:dagger-compiler:$rootProject.dagger_version"
api "android.arch.persistence.room:runtime:$rootProject.room_version"
kapt "android.arch.persistence.room:compiler:$rootProject.room_version"
testImplementation "android.arch.persistence.room:testing:$rootProject.room_version"
api "android.arch.persistence.room:rxjava2:$rootProject.room_version"
androidTestImplementation "android.arch.core:core-testing:$rootProject.room_version"
testImplementation "android.arch.core:core-testing:$rootProject.room_version"
api "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
api 'com.jakewharton.timber:timber:4.5.1'
api "com.android.support:multidex:1.0.3"
api "com.github.bumptech.glide:glide:$rootProject.glide_version"
api "jp.wasabeef:glide-transformations:$rootProject.glide_transformation_version"
api 'com.github.bumptech.glide:okhttp3-integration:1.5.0@aar'
api "io.reactivex.rxjava2:rxandroid:$rootProject.rxAndroid_version"
api "io.reactivex.rxjava2:rxjava:$rootProject.rxJava_version"
api "com.google.code.gson:gson:$rootProject.gson_version"
api("com.squareup.retrofit2:retrofit:$rootProject.retrofit_version") {
// exclude Retrofit’s OkHttp peer-dependency module and define your own module import
exclude module: 'okhttp'
}
api "com.squareup.okhttp3:okhttp:$rootProject.okhttp_version"
api "com.squareup.okhttp3:logging-interceptor:$rootProject.okhttp_version"
api "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofit_version"
api "com.squareup.retrofit2:converter-gson:$rootProject.retrofit_version"
api 'com.jakewharton.threetenabp:threetenabp:1.0.5'
api "com.google.firebase:firebase-invites:$rootProject.play_services_version"
api "com.google.firebase:firebase-core:$rootProject.play_services_version"
api "com.google.firebase:firebase-config:$rootProject.play_services_version"
api "com.google.firebase:firebase-perf:$rootProject.play_services_version"
api "com.google.firebase:firebase-auth:$rootProject.play_services_version"
api "com.google.firebase:firebase-firestore:$rootProject.play_services_version"
api("com.firebaseui:firebase-ui-auth:$rootProject.firebase_ui_version") {
// exclude Retrofit’s OkHttp peer-dependency module and define your own module import
exclude module: 'play-services-auth'
exclude module: 'firebase-auth'
}
// Required only if Facebook login support is required
api('com.facebook.android:facebook-android-sdk:4.31.0')
api "com.google.android.gms:play-services-auth:$rootProject.play_services_version"
// Required only if Twitter login support is required
api("com.twitter.sdk.android:twitter-core:3.0.0@aar") { transitive = true }
api 'com.jakewharton.rxbinding2:rxbinding-kotlin:2.0.0'
api 'com.jakewharton.rxbinding2:rxbinding-support-v4-kotlin:2.0.0'
api 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7-kotlin:2.0.0'
api 'com.jakewharton.rxbinding2:rxbinding-design-kotlin:2.0.0'
api('com.crashlytics.sdk.android:crashlytics:2.9.1@aar') {
transitive = true
}
}
I have also tried clean build and Rebuild project.
Any idea how can i resolve this issue ?
回答1:
I have tried several approaches including the solutions reported in this thread. I also found out that a lot of folks are facing this annoying problem as you can see here
Nevertheless, the most closest solution to this problem which has worked for me so far is removing apply plugin: kotlin-android-extensions
from gradle, Sync
gradle plugin and then add it again.
回答2:
I'm using Android Studio 3.1.3 and I encountered the same issue. I managed to solve this by moving all my codes from java/
to kotlin/
directory inside main/
.
app/
|-- src/
| |-- main/
| | |-- java/
| | | |-- com.example.android.app
| | |-- kotlin/ <-- (use this)
| | | |-- com.example.android.app
Then, add the kotlin/
as part of the source sets:
app/build.gradle
android {
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
Sometimes, it still requires to sync and rebuild the project to properly import the kotlinx.android....
Reference: Add kotlin code
回答3:
I have the same problem and I am trying to solve it for too many days...
One trick you can do is to Exclude from Import and Completion <package-name>.R.id.*
for project scope.
Go to Settings/Editor/Auto Import
to add it.
It improves our issue and if you do this and clean the project, it will work but it does not resolve the issue completely. Many times the imports reappear as unused imports and there is to clean the project over and over :-(.
EDITED
Also, another improvement I have achieved is working with include
s on XML. For example, if I am going to use "the same" button in several screens, I make a specific layout for this button and I re-use it on several activities / fragments. You can set the id within this specific layout and synthetic will auto-import it without generating conflicts, due to you have the content view reference declared before.
I show you a simple example:
activity_main.xml
<!-- ... -->
<include layout="@layout/btn_foo"/>
<!-- ... -->
btn_foo.xml
<?xml version="1.0" encoding="utf-8"?>
<Button
android:id="@+id/btnFoo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"/>
MainActivity.kt
// ...
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.btn_foo.*
// ...
setContentView(R.layout.activity_main)
// ...
btnFoo.setOnClickListener { }
I have to admit that in the other cases I have returned to the typical Hungarian convention whatWhereDescription(Size) to set the id
s due to is too much annoying to deal with imports among activities / fragments / view all the time.
回答4:
I've solved similar issues for ViewHolder implementations:
We have to inherit our ViewHolder class implementation from LayoutContainer. LayoutContainer is an interface available in kotlinx.android.extensions package.
You will have some code similar with this:
class TaskVH(override val containerView: View, val itemListener: TasksFragment.TaskItemListener) : RecyclerView.ViewHolder(containerView), LayoutContainer {
fun bindItem(task: Task) {
item_title.text = ""
item_complete.isChecked = task.isCompleted
itemView.setBackgroundResource(rowViewBackground)
itemView.setOnClickListener { itemListener.onTaskClick(task) }
}
}
回答5:
I don't know if this tripped anyone else up, but I was having problems because I didn't realize the synthetic objects are only available if you're inside an Activity
, Dialog
, or Fragment
. If you're in some other class (like using Conductor's Controller
) you're out of luck.
回答6:
There is an existing issue (which is assigned) on Google tracker regarding synthetic imports. https://issuetracker.google.com/issues/78547457
回答7:
For Conductor:
Create this base class.
import android.os.Bundle
import android.view.View
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.RestoreViewOnCreateController
abstract class BaseController(
bundle: Bundle? = null
) : RestoreViewOnCreateController(bundle){
init {
addLifecycleListener(object : LifecycleListener() {
override fun postCreateView(controller: Controller, view: View) {
onViewCreated(view)
}
})
}
open fun onViewCreated(view: View) { }
}
Then in your controller:
import kotlinx.android.synthetic.main.controller_example.view.*
class ProfileController : BaseController() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View {
return inflater.inflate(R.layout.controller_example, container, false)
}
override fun onViewCreated(view: View) {
view.txtName.text = "Example"
}
}
回答8:
I try every other solution bu no one worked for me. At the and I cloned project again and now it's working. I love android studio
回答9:
Cross-posting my bug report with workaround from here: https://issuetracker.google.com/issues/145888144
Original bug was closed as "fixed" by google, but it is definitely not fixed: https://issuetracker.google.com/issues/78547457
SUMMARY:
For some modules in a multi-module project, the IDE does not properly recognize imports for "synthetic" symbols that abstract view ids, a feature provided by the plugin 'kotlin-android-extensions'. This results in class files using these symbols appearing full of errors, as the imports are "unresolved", the symbols are then unknown, and of course anything using these symbols fail because the types are unknown.This is solely an IDE problem though; everything compiles normally and works as expected.
ROOT CAUSE
The kotlin-language facet is not being applied to the errant modules.
BACKGROUND
Facets in IntelliJ IDEA projects are configurable on a module-by-module basis in Project settings. In Android Studio, this part of the Project settings UI is missing (or suppressed.) Presumably, Android Studio is attempting to apply the correct facets based on the gradle plugins applied to each module. This process is /sometimes/ FAILING for this particular case; I have not been able to determine what triggers the success/failure of the process.
TEMPORARY WORKAROUND
This workaround works consistently, and has since 3.5.2 when I discovered it:
- Open the ".iml" file for the module you are trying to "fix" in Android Studio editor. (In AS > 4, the iml file is in
.idea/modules
, earlier than that it was in top-level of your module.) Find the<component name="FacetManager">
block, and notice that there is no facet called "kotlin-language" there. Paste the contents of the text block below so it appears within the<component name="FacetManager">
block. Save the file. - Re-import gradle.
This is a clumsy workaround, and has to be applied on a module-by-module basis. What's more, it may be required to sometimes re-apply the workaround after making changes to the build.gradle
file for an affected module. The hope is that Google (or JetBrains, if it turns out it is their problem) will fix this problem properly.
Given that kotlin-android-extensions
has fallen out of favor, I don't expect this bug will ever be fixed.
Text to use for the fix
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" allPlatforms="JVM [1.8]" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="jvmTarget" value="1.8" />
<option name="pluginOptions">
<array>
<option value="plugin:org.jetbrains.kotlin.android:enabled=true" />
<option value="plugin:org.jetbrains.kotlin.android:defaultCacheImplementation=hashMap" />
</array>
</option>
</compilerArguments>
</configuration>
</facet>
回答10:
Add id kotlin-android-extensions
in your build.gradle
file in the plugins
block.
Google removed this feature by default
来源:https://stackoverflow.com/questions/50015465/kotlinx-android-synthetic-unused-android-studio-issue