Thread
#compose
    e

    eschrag

    1 year ago
    I’m trying to figure out how to replicate some of the old drawable state list background color functionality, where the background color changed on press (with no ripple), and really struggling. any resources on how to accomplish this?
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    What exactly are you trying to do? Implement ripple from scratch? Add a touch ripple to a custom component?
    e

    eschrag

    1 year ago
    i just want to replicate the old state list behavior. if button is pressed, button background color is blue, otherwise it’s teal. no ripple at all.
    Colton Idle

    Colton Idle

    1 year ago
    Can't you just switch on state and change the color accordingly?
    Like background = if (PRESSED) Color.Blue else Color.Red
    e

    eschrag

    1 year ago
    i’d be happy to do that but the initial Material button colors implementation doesn’t account for any interaction state, only enabled
    @Stable
    interface ButtonColors {
        /**
         * Represents the background color for this button, depending on [enabled].
         *
         * @param enabled whether the button is enabled
         */
        @Composable
        fun backgroundColor(enabled: Boolean): State<Color>
    
        /**
         * Represents the content color for this button, depending on [enabled].
         *
         * @param enabled whether the button is enabled
         */
        @Composable
        fun contentColor(enabled: Boolean): State<Color>
    }
    and i’m not sure how to make an impl of this interface respect the interactionSource to get that PRESSED info in and updated
    i tried defining this custom ButtonColor impl:
    private class OurButtonColors(val pressed: State<Boolean>) : ButtonColors {
        @Composable
        override fun backgroundColor(enabled: Boolean): State<Color> {
            return if (pressed.value) {
                rememberUpdatedState(newValue = Color.Red)
            } else {
                rememberUpdatedState(newValue = Color.Magenta)
            }
        }
    
        @Composable
        override fun contentColor(enabled: Boolean): State<Color> {
            return rememberUpdatedState(newValue = Color.Green)
        }
    
    }
    and passed it `
    val isPressed = interactionSource.collectIsPressedAsState()
    `
    but that doesn’t change to red on press, and i’m kind of confused
    Colton Idle

    Colton Idle

    1 year ago
    I'm assuming material buttons probably adhere to material ripple spec, etc. But you should be able to copy paste that implementation and make whatever changes you need for your custom design system or just use the regular button.
    I'm also new to Compose so don't listen to me. But from what I gather... That's basically what you would do. Maybe @Louis Pullen-Freilich [G] would know better. But I think the idea of color state lists as you said doesn't really exist. Use state and you do whatever you want based on it.
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    l

    Louis Pullen-Freilich [G]

    1 year ago
    i just want to replicate the old state list behavior. if button is pressed, button background color is blue, otherwise it’s teal. no ripple at all.
    At this point it is probably easier just to build your own button, since ripple is a core part of Material components. Then you can just do:
    val isPressed = interactionSource.collectIsPressedAsState()
    
    val backgroundColor = if (isPressed) .. else ..
    
    Surface(backgroundColor...)
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    not to be pedantic, but ripple isn’t really a core part of material, it’s actually in its own dedicated library for compose: https://developer.android.com/reference/kotlin/androidx/compose/material/ripple/package-summary
    l

    Louis Pullen-Freilich [G]

    1 year ago
    Well, it’s a bit tricky - on Android in particular the line between Material design and the platform is a bit blurry. A ripple is explicitly Material design, but at the same time since Android devices and applications use ripples, even non-Material applications typically use ripples so the behaviour and feel is consistent with other applications on the device, similar to how the fling curve is constant. We moved ripple into its own module to make it easy for non-Material design applications to use it, without needing to bring in all of Material, but within Material every component uses a ripple and since this is explicitly part of the component’s spec, it’s not something that can be changed and replaced with something else.
    e

    eschrag

    1 year ago
    I figured out that my issue was simply that I wasn’t connecting my interactionSource to the button with
    interactionSource = interactionSource,
    in the Composable call