J'ai une classe linearlayout personnalisée et lorsque je veux créer une instance de cette classe, une erreur tarda la propriété n'a pas été initialisée J'utilise la dernière version de la bibliothèque butterknife
c'est ma classe de kotlin
class MenuItemView : LinearLayout {
@BindView(R.id.menu_title_text_view_id)
lateinit var menuTitleTextView : CTextBasic
constructor(ctx: Context) : super(ctx) {
}
init {
val view = LayoutInflater.from(context).inflate(R.layout.menu_item,this)
ButterKnife.bind(this,view)
}
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
val menuAttrs = context.theme.obtainStyledAttributes(attrs, R.styleable.MenuItemView, 0, 0)
try {
val title: String = menuAttrs.getString(R.styleable.MenuItemView_menu_title)
menuTitleTextView.text = title
}catch (e : Exception){
e.printStackTrace()
}finally {
menuAttrs.recycle()
}
}
fun setTitle( title : String){
menuTitleTextView.text = title
}
}
c'est le journal des erreurs
kotlin.UninitializedPropertyAccessException: lateinit property menuTitleTextView has not been initialized
at com.leavigstone.liberali.ui.custom.menu.MenuItemView.setTitle(MenuItemView.kt:48)
at com.leavigstone.liberali.ui.activities.MainActivity.onAddButtonClick(MainActivity.Java:142)
at com.leavigstone.liberali.ui.activities.MainActivity_ViewBinding$3.doClick(MainActivity_ViewBinding.Java:54)
at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.Java:22)
at Android.view.View.performClick(View.Java:4780)
at Android.view.View$PerformClick.run(View.Java:19866)
at Android.os.Handler.handleCallback(Handler.Java:739)
at Android.os.Handler.dispatchMessage(Handler.Java:95)
at Android.os.Looper.loop(Looper.Java:135)
at Android.app.ActivityThread.main(ActivityThread.Java:5254)
at Java.lang.reflect.Method.invoke(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:372)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:903)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:698)
Si vous ne souhaitez utiliser aucune bibliothèque tierce partie, vous pouvez ajouter ces fonctions d'extension (j'ai tendance à avoir un ContextExtensions.kt
ou ViewExtensions.kt
pour les fonctions d'extension Context ou View related), puis l'insérer.
inline fun <reified T : View> View.find(id: Int): T = findViewById(id) as T
inline fun <reified T : View> Activity.find(id: Int): T = findViewById(id) as T
inline fun <reified T : View> Fragment.find(id: Int): T = view?.findViewById(id) as T
ils vous permettent d’appeler find
depuis Activity
, Fragment
et View
s . Ainsi, dans votre classe, au lieu de
@BindView(R.id.menu_title_text_view_id) lateinit var menuTitleTextView : CTextBasic
vous pouvez avoir
val menuTitleTextView by lazy { find<CTextBasic>(R.id.menu_title_text_view_id) }
Pour des éléments tels que les interfaces utilisateur, il est préférable de val
au lieu de var
lorsqu'ils ne nécessitent pas de modification. En règle générale en programmation, essayez de garder les choses aussi immuables que possible, vous obtiendrez beaucoup moins de bugs.
Utilisez Kotterknife pour Butter Knife-esque View Binding pour Kotlin.
Ensuite, vous pouvez lier votre vue avec
val menuTitleTextView: CTextBasic by bindView(R.id.menu_title_text_view_id)
Dans mon cas, je ne construisais pas ButterKnife correctement. Assurez-vous d’importer son compilateur dans le fichier build.gradle de votre module:
...
// Butter Knife
implementation "com.jakewharton:butterknife:$butterKnifeVersion"
kapt "com.jakewharton:butterknife-compiler:$butterKnifeVersion"
...
La discussion sur les exemples de Jetbrain m'a permis de mieux comprendre ce problème.
Un autre problème est que vous pouvez accéder aux vues avant le conteneur a été créé. Voici une question liée à , la discussion y est spécifique aux propriétés synthétiques de kotlinx mais la même logique devrait s’appliquer à la reliure de vue de Butterknife
ajoutez apply plugin: 'kotlin-kapt'
au fichier build.gradle du niveau de l'application
exemple
apply plugin: 'com.Android.application'
apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-Android-extensions'
apply plugin: 'kotlin-kapt'
et dans la section des dépendances
implementation "com.jakewharton:butterknife:8.8.1"
kapt "com.jakewharton:butterknife-compiler:8.8.1"
J'espère que cela t'aides!
J'ai trouvé cela fonctionne pour moi.
Changez votre build.gradle
dans le module app
de votre projet.
dependencies {
compile "com.jakewharton:butterknife:8.8.1"
kapt "com.jakewharton:butterknife-compiler:8.8.1"
}
utilisez kapt
au lieu de annotationProcessor
.
et ensuite vous pouvez faire votre annotation ButterKnife familière comme ceci:
class MainActivity : AppCompatActivity() {
@BindView(R.id.myButton)
lateinit var myButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ButterKnife.bind(this)
//...
}
}
Prendre plaisir.