1
0
mirror of https://github.com/oliexdev/openScale.git synced 2025-10-28 14:25:17 +01:00

The clickable area around each measurement type icon now has a ripple effect, improving touch feedback. This was achieved by applying the clickable modifier directly to the RoundMeasurementIcon and removing the wrapping Column

This commit is contained in:
oliexdev
2025-10-02 19:54:59 +02:00
parent 99d46125bd
commit 06eaef4912
2 changed files with 34 additions and 39 deletions

View File

@@ -19,12 +19,15 @@ package com.health.openscale.ui.screen.components
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -35,6 +38,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
@@ -189,46 +193,42 @@ fun MeasurementTypeFilterRow(
val iconBackgroundColor = if (isSelected) Color(type.color) else MaterialTheme.colorScheme.surfaceVariant val iconBackgroundColor = if (isSelected) Color(type.color) else MaterialTheme.colorScheme.surfaceVariant
val iconColor = if (isSelected) Color.Black else MaterialTheme.colorScheme.onSurfaceVariant // Consider MaterialTheme.colorScheme.onPrimary for selected state if type.color is primary-like val iconColor = if (isSelected) Color.Black else MaterialTheme.colorScheme.onSurfaceVariant // Consider MaterialTheme.colorScheme.onPrimary for selected state if type.color is primary-like
Column( RoundMeasurementIcon(
horizontalAlignment = Alignment.CenterHorizontally, icon = type.icon.resource,
backgroundTint = iconBackgroundColor,
iconTint = iconColor,
size = iconSize,
modifier = Modifier modifier = Modifier
.padding(vertical = 4.dp) // Padding for touch target .clip(CircleShape)
.clickable { .clickable(
if (!isInitialized) { // Prevent clicks during initial setup enabled = isInitialized,
return@clickable onClick = {
} val currentSelectionMutable = displayedSelectedIds.toMutableList()
val currentlySelectedInList = type.id in currentSelectionMutable
val currentSelectionMutable = displayedSelectedIds.toMutableList() if (currentlySelectedInList) {
val currentlySelectedInList = type.id in currentSelectionMutable // Only allow deselection if empty selection is allowed or if more than one item is selected
if (allowEmptySelection || currentSelectionMutable.size > 1) {
if (currentlySelectedInList) { currentSelectionMutable.remove(type.id)
// Only allow deselection if empty selection is allowed or if more than one item is selected } else {
if (allowEmptySelection || currentSelectionMutable.size > 1) { // Prevent deselecting the last item if allowEmptySelection is false
currentSelectionMutable.remove(type.id) return@clickable
}
} else { } else {
// Prevent deselecting the last item if allowEmptySelection is false currentSelectionMutable.add(type.id)
return@clickable
} }
} else {
currentSelectionMutable.add(type.id)
}
val newSelectedIdsList = currentSelectionMutable.toList() val newSelectedIdsList = currentSelectionMutable.toList()
displayedSelectedIds = newSelectedIdsList displayedSelectedIds = newSelectedIdsList
onSelectionChanged(newSelectedIdsList) onSelectionChanged(newSelectedIdsList)
scope.launch { scope.launch {
val setToPersist = newSelectedIdsList.map { it.toString() }.toSet() val setToPersist = newSelectedIdsList.map { it.toString() }.toSet()
onPersistSelectedTypeIds(setToPersist) onPersistSelectedTypeIds(setToPersist)
}
} }
} )
) { )
RoundMeasurementIcon(
icon = type.icon.resource,
backgroundTint = iconBackgroundColor,
iconTint = iconColor
)
}
} }
} }
} }

View File

@@ -519,12 +519,7 @@ fun UserDetailScreen(
onValueChange = {}, onValueChange = {},
readOnly = true, readOnly = true,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
label = { label = { Text(stringResource(R.string.my_goals_label)) },
Text(
text = stringResource(R.string.my_goals_label),
style = MaterialTheme.typography.bodyLarge
)
},
trailingIcon = { trailingIcon = {
IconButton(onClick = { IconButton(onClick = {
val firstTargetableType = allMeasurementTypes.firstOrNull { val firstTargetableType = allMeasurementTypes.firstOrNull {