I have three `material.Button`s in a `Row` where I...
# compose
d
I have three `material.Button`s in a
Row
where I dynamically render buttons with different properties and have the strange ripple behaviour: the button which wasn't interacted with shows ripple effect for some reason. Notice the button in the center (video in the thread). Any ideas why this happens?
r
Could you share the code used to generate those buttons?
d
Unfortunatly that's several layers of custom components now, so this wouldn't be so easy. I can come up with minimal example, but I thought maybe someone would spot some known issue right away. Basically these are 3 buttons in a Row, they just have quite a few props customized.
r
not an expert here, but it looks like Compose is not tracking the buttons across the state changes… it’s as if it’s tracking the light and dark buttons separately. As if, when you click the first button, a new dark button appears to the left, and the original first button is now the 2nd button in the row with different text (but still the first light button), completing its ripple effect. Can you see anything in the code that might be confusing Compose about this?
If the code is using upper level wrapper components like DarkButton and LightButton that each call Button themselves, I could see that being the problem.
d
Yes, this is basically what happens: there are PrimaryButton and SecondaryButton components, each with preconfigured colors and they call Button internally. But not sure why compose would think this is the same button. Still maybe I should play with "key" specification, thanks for an idea.
r
You might be better off to have a single MyButton component that just knows how to set the Button properties based on its primary/secondary setting… This is more similar to how other components do it, like how you can provide a
style
to
Text
d
but that's what I do. I just have a few more shortcut components on top: which pre-set some properties so I won't have to repeat them each time. I.e. SecondaryButton just calls MyButton with colors and other props which in turn calls material button.
a
You need to write like this:
Copy code
@Composable
fun MyButton(selected: Boolean) { ... }

@Composable
fun App() {
    MyButton(selected = selectedState)
}
In this way both selected and unselected states are the same invocation. If you use something like this:
Copy code
@Composable
fun SelectedButton() { ... }

@Composable
fun UnselectedButton() { ... }

@Composable
fun App() {
    if (selectedState) {
        SelectedButton()
    } else {
        UnselectedButton()
    }
}
it won't work as
SelectedButton()
and
UnselectedButton()
are not the same invocation. When you switch
selectedState
basically what happens is that the old button is removed and the new button is added.
1
👍 3
d
Indeed, this is my case (the latter). Thank you, I'll reorganize like you've suggested! UPD that fixed it!