Edna Krabappel
Edna Krabappel

Reputation: 414

@Composable in a overridden method?

I would like to draw a @Composable on a override method, like

@Composable
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    Greeting()
}

Unfortunately, I can not mark a override onKeyDown() with @Composable, since I get:

Conflicting overloads: @Composable public open fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean defined in com.example.emptycompose.MainActivity, public open fun onKeyDown(p0: Int, p1: KeyEvent!): Boolean defined in androidx.appcompat.app.AppCompatActivity

How can I use a @Composable in e.g. a override onKeyDown()?

Upvotes: 3

Views: 2472

Answers (3)

jason.
jason.

Reputation: 375

@Composable can only be applied to an overriding function if the base function also has a @Composable annotation.

Whilst I'm pretty sure the provided example wouldn't work in the first place since it's an event listener (it won't be invoked in a @Composable context!), if you did have control over where the function is invoked, you could simply add the annotation:

interface Foo {
    @Composable // add this
    fun foo(): Unit
}

object Bar : Foo {
    @Composable // no error
    override fun foo(): Unit {
        Text("world, hello")
    }
}

Upvotes: 0

ksc91u
ksc91u

Reputation: 520

This happen when you rename your .kt file.

For example, I rename KKbutton.kt to KKButton.kt and this error happen.

Clean and rebuild fix this.

Upvotes: 0

RickSanchez725
RickSanchez725

Reputation: 329

You can't directly return an instance of a composable like that, but you can have a composable that observes changes and recomposes automatically.

In your ViewModel create a MutableLiveData that holds the slider position.

    val sliderPosition = MutableLiveData<Integer>()

In your Activity, have onKeyDown update the MutableLiveData:

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    when (event?.keyCode) {
        KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> {
            viewModel.sliderPosition.value = getCurrentSliderPosition()
        }
    }
}

Then pass the ViewModel as a parameter to your composable function and then you can observe volume changes like this:

   val position by viewModel.sliderPosition.observeAsState(0)

Now you can just use position as a regular variable in your layout, but when it changes, the Composable will be automatically updated with the new value.

You can read more on managing state with Compose here.

As a side note, there is an experimental (at the time of the answer) keyInputFilter Modifier you may want to check out.

Upvotes: 0

Related Questions