j

    jaqxues

    2 years ago
    I am using a Switch, and adding Padding to the Modifier doesnt increase the clickable, swipeable area . The Switch is unusable with its Hitbox being this small Is there any way I can increase it with a Modifier or any other way?
    Timo Drick

    Timo Drick

    2 years ago
    The order of the modifiers matter. So first call the clickable modifier than the padding
    j

    jaqxues

    2 years ago
    yes, how
    @Composable
    @OptIn(ExperimentalMaterialApi::class)
    fun Switch(
        checked: Boolean,
        onCheckedChange: (Boolean) -> Unit,
        modifier: Modifier = Modifier,
        enabled: Boolean = true,
        color: Color = MaterialTheme.colors.secondaryVariant
    ) {
        val minBound = 0f
        val maxBound = with(DensityAmbient.current) { ThumbPathLength.toPx() }
        val swipeableState = rememberSwipeableStateFor(checked, onCheckedChange, AnimationSpec)
        val interactionState = remember { InteractionState() }
        val isRtl = LayoutDirectionAmbient.current == LayoutDirection.Rtl
        Stack(
            modifier
                .toggleable(
                    value = checked,
                    onValueChange = onCheckedChange,
                    enabled = enabled,
                    interactionState = interactionState,
                    indication = null
                )
                .swipeable(
                    state = swipeableState,
                    anchors = mapOf(minBound to false, maxBound to true),
                    thresholds = { _, _ -> FractionalThreshold(0.5f) },
                    orientation = Orientation.Horizontal,
                    enabled = enabled,
                    reverseDirection = isRtl,
                    interactionState = interactionState,
                    resistanceFactorAtMin = 0f,
                    resistanceFactorAtMax = 0f
                )
                .padding(DefaultSwitchPadding)
        ) {
            SwitchImpl(
                checked = checked,
                enabled = enabled,
                checkedColor = color,
                thumbValue = swipeableState.offset,
                interactionState = interactionState
            )
        }
    }
    this is the switch implementation from androidx.compose.material.Switch
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    2 years ago
    You'd have to add your own clickable modifier, which would look odd visually and not support dragging to toggle, to increase the hit area like this. I don't think there's currently a way to do it without changing the implementation of Switch itself, might be worth filing a bug?
    j

    jaqxues

    2 years ago
    yeah, thats what I thought, will do
    the bugreport belongs on the issuetracker.google.com right? in
    Android Public Tracker > App Development > Jetpack Compose > UI Libraries > Material
    i suppose?
    matvei

    matvei

    2 years ago
    Thanks for filing this. It won't work if you're setting padding, as it will behaves like outer padding and it's expected to not to pick up toggleable
    Have you tried to put
    Modifier.size
    on the Switch?
    That should do the trick
    And if it doesn't -- than we need to fix it
    j

    jaqxues

    2 years ago
    this results in some weird design issue
    matvei

    matvei

    2 years ago
    Hm, I see. But click works on the whole area, doesn't it?
    j

    jaqxues

    2 years ago
    no
    var isActive by remember { mutableStateOf(true) }
    Switch(isActive, onCheckedChange = { isActive = it }, color = Color(0xFF00AA00), modifier = Modifier.size(48.dp).padding(horizontal = 16.dp))
    matvei

    matvei

    2 years ago
    Oh, what I meant is that you need to remove padding completely, sorry
    j

    jaqxues

    2 years ago
    alright
    still the same
    matvei

    matvei

    2 years ago
    It seems like this visual artifact is a separate issue you're hitting
    Thanks for filing this, I will take a look. In general
    var isActive by remember { mutableStateOf(true) }
    Switch(isActive, onCheckedChange = { isActive = it }, color = Color(0xFF00AA00), modifier = Modifier.size(48.dp))
    This should result with proper switch, clickable within all 48dps and centered within this 48.dp box
    Padding modifier shouldn't work and this is by design, because this padding comes before toggleable (as you provide it for the whole Switch) and will pad the toggleable area as well
    j

    jaqxues

    2 years ago
    Yes, thanks for looking into it!
    matvei

    matvei

    2 years ago
    Filed http://issuetracker.google.com/issues/167550767 for a broken Switch UI when size is set explicitly, thanks!
    j

    jaqxues

    2 years ago
    Actually the intended behaviour implies there is no way to simply make the "hitbox" itself (toggleable + swipeable area) bigger, and not the entire Switch. So if you want a bigger Hitbox, you need a bigger UI-Element right?
    matvei

    matvei

    2 years ago
    Switch itself is a fixed density dependent size always and will never scale no matter the hitbox, so passing Modifier.size will increase toggeable and draggable area, while switch will be the same size and centered
    j

    jaqxues

    2 years ago
    Alright, sounds good then, thanks!
    I've just seen it's fixed, thank you!
    matvei

    matvei

    2 years ago
    No problem, thanks for reporting it!