简体   繁体   English

lateinit 属性尚未初始化

[英]lateinit property has not been initialized

I have a custom linearlayout class and when I want to create instance of this class, I get the following error:我有一个自定义线性布局类,当我想创建此类的实例时,出现以下错误:
lateinit property has not been initialized lateinit 属性尚未初始化

I'm using the latest version of butterknife library.我正在使用最新版本的黄油刀库。

The following is my Kotlin class:以下是我的 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
}
}

Error Log错误日志

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)

If you don't want to use any thirdparty libraries, you can add these extension functions (I tend to have a ContextExtensions.kt or ViewExtensions.kt for Context or View related extension functions), then put in it如果不想使用任何第三方库,可以添加这些扩展函数(我倾向于有一个ContextExtensions.ktViewExtensions.kt用于Context或View相关的扩展函数),然后放入

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

these let you call find from within Activity , Fragment , and View s.这些让您可以从ActivityFragmentView中调用find So inside your class instead of所以在你的课堂上而不是

@BindView(R.id.menu_title_text_view_id) lateinit var menuTitleTextView : CTextBasic

you can have你可以有

val menuTitleTextView by lazy { find<CTextBasic>(R.id.menu_title_text_view_id) }

For things like UIs, it's better to val instead of var when they don't need to change.对于 UI 之类的东西,当它们不需要更改时,最好使用val而不是var As a general rule in programming, try to keep things as immutable as possible, you would get far less bugs.作为编程的一般规则,尽量使事物保持不变,这样会少得多的错误。

I found this works for me.我发现 对我有用。

Change your build.gradle in your project app module.在您的项目app模块中更改您的build.gradle

dependencies {
    compile "com.jakewharton:butterknife:8.8.1"
    kapt "com.jakewharton:butterknife-compiler:8.8.1"
}

use kapt instead of annotationProcessor .使用kapt而不是annotationProcessor

and then you can do your familiar ButterKnife annotation like this:然后你可以像这样做你熟悉的 ButterKnife 注释:

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)
        //...
    }
}

Enjoy.享受。

add apply plugin: 'kotlin-kapt' to the app level build.gradle fileapply plugin: 'kotlin-kapt'添加到应用级 build.gradle 文件

example例子

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

and in dependencies section并在依赖项部分

implementation "com.jakewharton:butterknife:8.8.1"
kapt "com.jakewharton:butterknife-compiler:8.8.1"

Hope this Helps!希望这可以帮助!

Use Kotterknife for Butter Knife-esque View Binding for Kotlin.Kotterknife用于 Kotlin 的黄油刀式视图绑定。

Then you can bind your View with然后你可以绑定你的视图

val menuTitleTextView: CTextBasic by bindView(R.id.menu_title_text_view_id)

In my case, I wasn't building ButterKnife correctly.就我而言,我没有正确构建 ButterKnife。 Make sure you're importing its compiler in your module's build.gradle:确保在模块的 build.gradle 中导入其编译器:

...
// Butter Knife
implementation "com.jakewharton:butterknife:$butterKnifeVersion"
kapt "com.jakewharton:butterknife-compiler:$butterKnifeVersion"
...

The discussion at Jetbrain's samples thread shed more light on this issue for me. Jetbrain 的示例线程上的讨论为我提供了更多关于这个问题的信息。

Another issue is that you might be accessing the views before the container has been created.另一个问题是您可能在创建容器之前访问视图。 Here is a related question , the discussion there is specific to kotlinx synthetic properties but same logic should apply to Butterknife view binding这是一个相关的问题,那里的讨论特定于 kotlinx 合成属性,但同样的逻辑应该适用于 Butterknife 视图绑定

for me this error happens when include same layout several time对我来说,当多次include相同的布局时会发生此错误

for example例如

 <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <include layout="@layout/chart_bar_layout" />

 </LinearLayout>
 ...
 <include layout="@layout/chart_bar_layout" /> 

So find and remove that line make app work fine所以找到并删除该行使应用程序正常工作

There's a small trick you can try it by using Platform.runLater您可以使用Platform.runLater尝试一个小技巧

 init {
        Platform.runLater {
        ....
        }
 }

Faced this issue while, the problem was optional mark (?)遇到这个问题时,问题是可选标记(?)

wrong: lateinit var temp_model: ArrayList<MyModel?>错误: lateinit var temp_model: ArrayList<MyModel?>

Right: var temp_model = ArrayList< MyModel >()右: var temp_model = ArrayList< MyModel >()

Your initializer block is not called.未调用您的初始化程序块。 It only gets called when your primary constructor gets called.只有在调用主构造函数时才会调用它。 In your case, the secondary constructor gets used when view objects get created from xml layouts.在您的情况下,从 xml 布局创建视图对象时会使用辅助构造函数。

Change your init{...} block to fun init(){...} and call it as first statement in every constructor将您的init{...}块更改为fun init(){...}并将其作为每个构造函数中的第一条语句调用

You forgot to add the constructor你忘了添加构造函数

constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

=> add it and call init() in it => 添加它并在其中调用init()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM