0

I am trying to add a function to enable/disable some buttons in my fragment, however I am getting a compilation error

"Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable reciever"

I have tried a couple of different methods; from calling the button directly, to calling the activity where I would do the button work, but I get the same error:

private fun enableButtons(buttonState: Boolean) {
    (activity as MainActivity?).enableButtons(buttonState)
    //                         ^ error there
}

and

    var button = activity.findViewById(R.id.button0) as Button
    //                   ^ error here
    button.isEnabled = false
    button.isClickable = false

I'm pretty new to Kotlin and can't work out how can I access the buttons without passing in a view

Rob
  • 335
  • 8
  • 23
  • 1
    Also, to answer your last question, in order to access the buttons without passing a view you may use viewBinding or dataBinding: https://developer.android.com/topic/libraries/view-binding – JustSightseeing Dec 22 '22 at 11:21
  • you should simply make your statement nullable, you can't call enableButtons on a null object, so by adding ? after your closing bracket you are making sure enableButtons fun will not be called if the casting returns null. (activity as MainActivity?)?.enableButtons(buttonState) – Serdar Samancıoğlu Dec 22 '22 at 11:59

3 Answers3

1

Well, it is kinda suggesting what you have to do:

"Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable reciever"

Means that whatever variable you are using, might be null. So if you tried running

(activity as MainActivity?).enableButtons(buttonState)

this might end up as:

null.enableButtons(buttonState)

which (you may already know) will cause a crash

All kotlin is asking for is an alternative (when the variable is in fact null) or a "promise" that the variable is not null (!!)

A simple fix would be just to use:

(activity as MainActivity?)!!.enableButtons(buttonState)

or just remove ? after MainActivity

(more on .? and !! you can find here: What's the difference between !! and ? in Kotlin?)

JustSightseeing
  • 1,460
  • 3
  • 17
  • 37
1

If you are unsure if activity can be null you should use the following syntax:

(activity as MainActivity?)?.enableButtons(buttonState)

The others have suggested force unwrapping however that means if activity does end up being null your app will crash.

This goes for any optional value:

var button = activity?.findViewById<Button>(R.id.button0)

now if you want to use that button again you can simply use the null safety syntax:

button?.setOnClickListener { 
    // do stuff           
}

For more information about null safety check this out: https://kotlinlang.org/docs/null-safety.html#checking-for-null-in-conditions

Robin
  • 704
  • 8
  • 24
1

Solution 1

Remove ? in front of MainActivity

(activity as MainActivity).enableButtons(buttonState)

Solution 2

Add ? in front of (activity as MainActivity?)

(activity as MainActivity?)?.enableButtons(buttonState)

Note: There are rare cases that MainActivity get's null. So, the best solution is above among is 1st one.

Sohaib Ahmed
  • 1,990
  • 1
  • 5
  • 23