lateinit property action has not been initialized in kotlin, how to fix it?

Viewed 1322
import android.app.Dialog
import android.app.TimePickerDialog
import android.os.Bundle
import android.text.format.DateFormat
import android.widget.TimePicker
import androidx.fragment.app.DialogFragment
import java.util.*

class TimePickerFragment : DialogFragment(), TimePickerDialog.OnTimeSetListener {

     lateinit var action : (String) -> Unit

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        // Use the current time as the default values for the picker
        val c = Calendar.getInstance()
        val hour = c.get(Calendar.HOUR_OF_DAY)
        val minute = c.get(Calendar.MINUTE)

        // Create a new instance of TimePickerDialog and return it
        return TimePickerDialog(activity, this, hour, minute, DateFormat.is24HourFormat(activity))
    }

    override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int) {
        var min = minute.toString()
        if(min.toInt() < 10) min = "0$min"
        action("$hourOfDay:$min")
    }


    fun setListener(action: (String) -> Unit) {
        this.action = action
    }
}

my declare action was detected error in firebase inside fun setlistener this.action=action how to fix it? sorry i am newbie guys, i am need more references , thank you

2 Answers

The lateinit field holds a reference to the listener that does something with the result of the time that you've picked.

So if you show the picker dialog without setting that listener first, when the onTimeSet(..) function is called, which happens when you tap "OK" on the picker dialog, the action field still hasn't been initialised, so an UninitializedPropertyAccessException will be thrown.

You just need to set the action listener using the setListener(..) function beforehand. It can even be empty as shown below.

val dialog = TimePickerFragment()

dialog.setListener {
    // your listener logic
}

dialog.show(supportFragmentManager, "fragment-tag")

Update: In onTimeSet, you are passing a string to action(..). In your code, action is a listener that does something with the string that you pass to it. But you are passing a String to the listener before it has been set to anything, that is why you are seeing an error.

lateinit fields must be set before they can be used.

The quickest modification to your existing class would be to apply a listener by default:

// Create a new instance of TimePickerDialog and return it
return TimePickerDialog(activity, this, hour, minute, DateFormat.is24HourFormat(activity)).apply {
    action = { dateTimeString ->
        Log.d("LOG_TAG", "Time Selected -> $dateTimeString") // this outputs the String defined in onTimeSet to Logcat
    }
}

Then if you want to assign a different listener, you do so with setListener().

Just before the function that uses the variable or instance, initialise it to a reasonable value or use this if its part of the class constructors

Related