lateinit property has not been initialized

81,745

Solution 1

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

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 Views. 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. As a general rule in programming, try to keep things as immutable as possible, you would get far less bugs.

Solution 2

I found this works for me.

Change your build.gradle in your project app module.

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

use kapt instead of annotationProcessor.

and then you can do your familiar ButterKnife annotation like this:

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.

Solution 3

add apply plugin: 'kotlin-kapt' to the app level build.gradle file

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!

Solution 4

Use Kotterknife for Butter Knife-esque View Binding for Kotlin.

Then you can bind your View with

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

Solution 5

In my case, I wasn't building ButterKnife correctly. Make sure you're importing its compiler in your module's 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.

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

Share:
81,745
Jemo Mgebrishvili
Author by

Jemo Mgebrishvili

Kt. &amp; Android developer.

Updated on June 16, 2021

Comments

  • Jemo Mgebrishvili
    Jemo Mgebrishvili about 3 years

    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

    I'm using the latest version of butterknife library.

    The following is my Kotlin class:

    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)