Loading packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ButtonComponent.kt +17 −4 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.Expandable import com.android.systemui.Flags import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.compose.Icon import com.android.systemui.volume.panel.component.button.ui.viewmodel.ButtonViewModel Loading @@ -56,7 +57,7 @@ import kotlinx.coroutines.flow.StateFlow /** [ComposeVolumePanelUiComponent] implementing a clickable button from a bottom row. */ class ButtonComponent( private val viewModelFlow: StateFlow<ButtonViewModel?>, private val onClick: (expandable: Expandable, horizontalGravity: Int) -> Unit private val onClick: (expandable: Expandable, horizontalGravity: Int) -> Unit, ) : ComposeVolumePanelUiComponent { @Composable Loading Loading @@ -84,14 +85,26 @@ class ButtonComponent( }, color = if (viewModel.isActive) { if (Flags.volumeRedesign()) { MaterialTheme.colorScheme.primary } else { MaterialTheme.colorScheme.tertiaryContainer } } else { if (Flags.volumeRedesign()) { MaterialTheme.colorScheme.surfaceContainerHigh } else { MaterialTheme.colorScheme.surface } }, shape = RoundedCornerShape(20.dp), contentColor = if (viewModel.isActive) { if (Flags.volumeRedesign()) { MaterialTheme.colorScheme.onPrimary } else { MaterialTheme.colorScheme.onTertiaryContainer } } else { MaterialTheme.colorScheme.onSurface }, Loading packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ToggleButtonComponent.kt +25 −10 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import androidx.compose.ui.semantics.toggleableState import androidx.compose.ui.state.ToggleableState import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.systemui.Flags import com.android.systemui.common.ui.compose.Icon import com.android.systemui.volume.panel.component.button.ui.viewmodel.ButtonViewModel import com.android.systemui.volume.panel.ui.composable.ComposeVolumePanelUiComponent Loading @@ -51,7 +52,7 @@ import kotlinx.coroutines.flow.StateFlow /** [ComposeVolumePanelUiComponent] implementing a toggleable button from a bottom row. */ class ToggleButtonComponent( private val viewModelFlow: StateFlow<ButtonViewModel?>, private val onCheckedChange: (isChecked: Boolean) -> Unit private val onCheckedChange: (isChecked: Boolean) -> Unit, ) : ComposeVolumePanelUiComponent { @Composable Loading @@ -68,16 +69,30 @@ class ToggleButtonComponent( BottomComponentButtonSurface { val colors = if (viewModel.isActive) { if (Flags.volumeRedesign()) { ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.primary, contentColor = MaterialTheme.colorScheme.onPrimary, ) } else { ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.tertiaryContainer, contentColor = MaterialTheme.colorScheme.onTertiaryContainer, ) } } else { if (Flags.volumeRedesign()) { ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, contentColor = MaterialTheme.colorScheme.onSurface, ) } else { ButtonDefaults.buttonColors( containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onSurfaceVariant, ) } } Button( modifier = Modifier.fillMaxSize().padding(8.dp).semantics { Loading @@ -93,7 +108,7 @@ class ToggleButtonComponent( onClick = { onCheckedChange(!viewModel.isActive) }, shape = RoundedCornerShape(20.dp), colors = colors, contentPadding = PaddingValues(0.dp) contentPadding = PaddingValues(0.dp), ) { Icon(modifier = Modifier.size(24.dp), icon = viewModel.icon) } Loading packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt +74 −9 Original line number Diff line number Diff line Loading @@ -37,11 +37,13 @@ import androidx.compose.foundation.layout.size import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role Loading @@ -51,8 +53,11 @@ import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.PlatformIconButton import com.android.compose.PlatformSliderColors import com.android.compose.modifiers.padding import com.android.compose.modifiers.thenIf import com.android.systemui.Flags import com.android.systemui.res.R import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderViewModel Loading Loading @@ -84,7 +89,11 @@ fun ColumnVolumeSliders( val sliderPadding by topSliderPadding(isExpandable) VolumeSlider( modifier = Modifier.padding(end = { sliderPadding.roundToPx() }).fillMaxWidth(), modifier = Modifier.thenIf(!Flags.volumeRedesign()) { Modifier.padding(end = { sliderPadding.roundToPx() }) } .fillMaxWidth(), state = sliderState, onValueChange = { newValue: Float -> sliderViewModel.onValueChanged(sliderState, newValue) Loading @@ -93,9 +102,22 @@ fun ColumnVolumeSliders( onIconTapped = { sliderViewModel.toggleMuted(sliderState) }, sliderColors = sliderColors, hapticsViewModelFactory = sliderViewModel.getSliderHapticsViewModelFactory(), button = if (Flags.volumeRedesign()) { { ExpandButton( isExpanded = isExpanded, isExpandable = isExpandable, onExpandedChanged = onExpandedChanged, ) } } else { null }, ) ExpandButton( if (!Flags.volumeRedesign()) { ExpandButtonLegacy( modifier = Modifier.align(Alignment.CenterEnd), isExpanded = isExpanded, isExpandable = isExpandable, Loading @@ -103,6 +125,7 @@ fun ColumnVolumeSliders( sliderColors = sliderColors, ) } } AnimatedVisibility( visible = isExpanded || !isExpandable, label = "CollapsableSliders", Loading Loading @@ -153,7 +176,7 @@ fun ColumnVolumeSliders( } @Composable private fun ExpandButton( private fun ExpandButtonLegacy( isExpanded: Boolean, isExpandable: Boolean, onExpandedChanged: (Boolean) -> Unit, Loading Loading @@ -200,6 +223,48 @@ private fun ExpandButton( } } @Composable private fun ExpandButton( isExpanded: Boolean, isExpandable: Boolean, onExpandedChanged: (Boolean) -> Unit, modifier: Modifier = Modifier, ) { val expandButtonStateDescription = if (isExpanded) { stringResource(R.string.volume_panel_expanded_sliders) } else { stringResource(R.string.volume_panel_collapsed_sliders) } AnimatedVisibility( modifier = modifier, visible = isExpandable, enter = expandButtonEnterTransition(), exit = expandButtonExitTransition(), ) { PlatformIconButton( modifier = Modifier.size(width = 48.dp, height = 40.dp).semantics { role = Role.Switch stateDescription = expandButtonStateDescription }, onClick = { onExpandedChanged(!isExpanded) }, colors = IconButtonDefaults.iconButtonColors( containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onSurfaceVariant, ), iconResource = if (isExpanded) { R.drawable.ic_arrow_down_24dp } else { R.drawable.ic_arrow_up_24dp }, contentDescription = null, ) } } private fun enterTransition(index: Int, totalCount: Int): EnterTransition { val enterDelay = ((totalCount - index + 1) * 10).coerceAtLeast(0) val enterDuration = (EXPAND_DURATION_MILLIS - enterDelay).coerceAtLeast(100) Loading packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt +105 −2 Original line number Diff line number Diff line Loading @@ -24,9 +24,18 @@ import androidx.compose.animation.fadeOut import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.getValue Loading @@ -48,6 +57,7 @@ import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.unit.dp import com.android.compose.PlatformSlider import com.android.compose.PlatformSliderColors import com.android.systemui.Flags import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.ui.compose.Icon import com.android.systemui.compose.modifiers.sysuiResTag Loading @@ -61,11 +71,104 @@ import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.Sl fun VolumeSlider( state: SliderState, onValueChange: (newValue: Float) -> Unit, onValueChangeFinished: (() -> Unit)? = null, onIconTapped: () -> Unit, sliderColors: PlatformSliderColors, modifier: Modifier = Modifier, hapticsViewModelFactory: SliderHapticsViewModel.Factory?, onValueChangeFinished: (() -> Unit)? = null, button: (@Composable () -> Unit)? = null, ) { if (!Flags.volumeRedesign()) { LegacyVolumeSlider( state = state, onValueChange = onValueChange, onIconTapped = onIconTapped, sliderColors = sliderColors, onValueChangeFinished = onValueChangeFinished, modifier = modifier, hapticsViewModelFactory = hapticsViewModelFactory, ) return } val value by valueState(state) Column(modifier) { Row( horizontalArrangement = Arrangement.spacedBy(12.dp), modifier = Modifier.fillMaxWidth(), ) { state.icon?.let { Icon( icon = it, tint = MaterialTheme.colorScheme.onSurface, modifier = Modifier.size(40.dp).padding(8.dp), ) } Text( text = state.label, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.weight(1f).align(Alignment.CenterVertically), ) button?.invoke() } Slider( value = value, valueRange = state.valueRange, onValueChange = onValueChange, onValueChangeFinished = onValueChangeFinished, enabled = state.isEnabled, modifier = Modifier.height(40.dp).sysuiResTag(state.label).clearAndSetSemantics { if (state.isEnabled) { contentDescription = state.label state.a11yClickDescription?.let { customActions = listOf( CustomAccessibilityAction(it) { onIconTapped() true } ) } state.a11yStateDescription?.let { stateDescription = it } progressBarRangeInfo = ProgressBarRangeInfo(state.value, state.valueRange) } else { disabled() contentDescription = state.disabledMessage?.let { "${state.label}, $it" } ?: state.label } setProgress { targetValue -> val targetDirection = when { targetValue > value -> 1 targetValue < value -> -1 else -> 0 } val newValue = (value + targetDirection * state.a11yStep).coerceIn( state.valueRange.start, state.valueRange.endInclusive, ) onValueChange(newValue) true } }, ) } } @Composable private fun LegacyVolumeSlider( state: SliderState, onValueChange: (newValue: Float) -> Unit, onIconTapped: () -> Unit, sliderColors: PlatformSliderColors, hapticsViewModelFactory: SliderHapticsViewModel.Factory?, modifier: Modifier = Modifier, onValueChangeFinished: (() -> Unit)? = null, ) { val value by valueState(state) val interactionSource = remember { MutableInteractionSource() } Loading Loading @@ -178,7 +281,7 @@ private fun valueState(state: SliderState): State<Float> { val shouldSkipAnimation = prevState is SliderState.Empty || prevState.isEnabled != state.isEnabled val value = if (shouldSkipAnimation) mutableFloatStateOf(state.value) if (shouldSkipAnimation) remember { mutableFloatStateOf(state.value) } else animateFloatAsState(targetValue = state.value, label = "VolumeSliderValueAnimation") prevState = state return value Loading packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSliderContent.kt +3 −3 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ private enum class VolumeSliderContentComponent { DisabledMessage, } /** Shows label of the [VolumeSlider]. Also shows [disabledMessage] when not [isEnabled]. */ /** Shows label of the [LegacyVolumeSlider]. Also shows [disabledMessage] when not [isEnabled]. */ @Composable fun VolumeSliderContent( label: String, Loading Loading @@ -89,7 +89,7 @@ fun VolumeSliderContent( } } }, measurePolicy = VolumeSliderContentMeasurePolicy(isEnabled) measurePolicy = VolumeSliderContentMeasurePolicy(isEnabled), ) } Loading @@ -102,7 +102,7 @@ private class VolumeSliderContentMeasurePolicy(private val isEnabled: Boolean) : override fun MeasureScope.measure( measurables: List<Measurable>, constraints: Constraints constraints: Constraints, ): MeasureResult { val labelPlaceable = measurables Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ButtonComponent.kt +17 −4 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.Expandable import com.android.systemui.Flags import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.compose.Icon import com.android.systemui.volume.panel.component.button.ui.viewmodel.ButtonViewModel Loading @@ -56,7 +57,7 @@ import kotlinx.coroutines.flow.StateFlow /** [ComposeVolumePanelUiComponent] implementing a clickable button from a bottom row. */ class ButtonComponent( private val viewModelFlow: StateFlow<ButtonViewModel?>, private val onClick: (expandable: Expandable, horizontalGravity: Int) -> Unit private val onClick: (expandable: Expandable, horizontalGravity: Int) -> Unit, ) : ComposeVolumePanelUiComponent { @Composable Loading Loading @@ -84,14 +85,26 @@ class ButtonComponent( }, color = if (viewModel.isActive) { if (Flags.volumeRedesign()) { MaterialTheme.colorScheme.primary } else { MaterialTheme.colorScheme.tertiaryContainer } } else { if (Flags.volumeRedesign()) { MaterialTheme.colorScheme.surfaceContainerHigh } else { MaterialTheme.colorScheme.surface } }, shape = RoundedCornerShape(20.dp), contentColor = if (viewModel.isActive) { if (Flags.volumeRedesign()) { MaterialTheme.colorScheme.onPrimary } else { MaterialTheme.colorScheme.onTertiaryContainer } } else { MaterialTheme.colorScheme.onSurface }, Loading
packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ToggleButtonComponent.kt +25 −10 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import androidx.compose.ui.semantics.toggleableState import androidx.compose.ui.state.ToggleableState import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.systemui.Flags import com.android.systemui.common.ui.compose.Icon import com.android.systemui.volume.panel.component.button.ui.viewmodel.ButtonViewModel import com.android.systemui.volume.panel.ui.composable.ComposeVolumePanelUiComponent Loading @@ -51,7 +52,7 @@ import kotlinx.coroutines.flow.StateFlow /** [ComposeVolumePanelUiComponent] implementing a toggleable button from a bottom row. */ class ToggleButtonComponent( private val viewModelFlow: StateFlow<ButtonViewModel?>, private val onCheckedChange: (isChecked: Boolean) -> Unit private val onCheckedChange: (isChecked: Boolean) -> Unit, ) : ComposeVolumePanelUiComponent { @Composable Loading @@ -68,16 +69,30 @@ class ToggleButtonComponent( BottomComponentButtonSurface { val colors = if (viewModel.isActive) { if (Flags.volumeRedesign()) { ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.primary, contentColor = MaterialTheme.colorScheme.onPrimary, ) } else { ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.tertiaryContainer, contentColor = MaterialTheme.colorScheme.onTertiaryContainer, ) } } else { if (Flags.volumeRedesign()) { ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, contentColor = MaterialTheme.colorScheme.onSurface, ) } else { ButtonDefaults.buttonColors( containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onSurfaceVariant, ) } } Button( modifier = Modifier.fillMaxSize().padding(8.dp).semantics { Loading @@ -93,7 +108,7 @@ class ToggleButtonComponent( onClick = { onCheckedChange(!viewModel.isActive) }, shape = RoundedCornerShape(20.dp), colors = colors, contentPadding = PaddingValues(0.dp) contentPadding = PaddingValues(0.dp), ) { Icon(modifier = Modifier.size(24.dp), icon = viewModel.icon) } Loading
packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt +74 −9 Original line number Diff line number Diff line Loading @@ -37,11 +37,13 @@ import androidx.compose.foundation.layout.size import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role Loading @@ -51,8 +53,11 @@ import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.PlatformIconButton import com.android.compose.PlatformSliderColors import com.android.compose.modifiers.padding import com.android.compose.modifiers.thenIf import com.android.systemui.Flags import com.android.systemui.res.R import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderViewModel Loading Loading @@ -84,7 +89,11 @@ fun ColumnVolumeSliders( val sliderPadding by topSliderPadding(isExpandable) VolumeSlider( modifier = Modifier.padding(end = { sliderPadding.roundToPx() }).fillMaxWidth(), modifier = Modifier.thenIf(!Flags.volumeRedesign()) { Modifier.padding(end = { sliderPadding.roundToPx() }) } .fillMaxWidth(), state = sliderState, onValueChange = { newValue: Float -> sliderViewModel.onValueChanged(sliderState, newValue) Loading @@ -93,9 +102,22 @@ fun ColumnVolumeSliders( onIconTapped = { sliderViewModel.toggleMuted(sliderState) }, sliderColors = sliderColors, hapticsViewModelFactory = sliderViewModel.getSliderHapticsViewModelFactory(), button = if (Flags.volumeRedesign()) { { ExpandButton( isExpanded = isExpanded, isExpandable = isExpandable, onExpandedChanged = onExpandedChanged, ) } } else { null }, ) ExpandButton( if (!Flags.volumeRedesign()) { ExpandButtonLegacy( modifier = Modifier.align(Alignment.CenterEnd), isExpanded = isExpanded, isExpandable = isExpandable, Loading @@ -103,6 +125,7 @@ fun ColumnVolumeSliders( sliderColors = sliderColors, ) } } AnimatedVisibility( visible = isExpanded || !isExpandable, label = "CollapsableSliders", Loading Loading @@ -153,7 +176,7 @@ fun ColumnVolumeSliders( } @Composable private fun ExpandButton( private fun ExpandButtonLegacy( isExpanded: Boolean, isExpandable: Boolean, onExpandedChanged: (Boolean) -> Unit, Loading Loading @@ -200,6 +223,48 @@ private fun ExpandButton( } } @Composable private fun ExpandButton( isExpanded: Boolean, isExpandable: Boolean, onExpandedChanged: (Boolean) -> Unit, modifier: Modifier = Modifier, ) { val expandButtonStateDescription = if (isExpanded) { stringResource(R.string.volume_panel_expanded_sliders) } else { stringResource(R.string.volume_panel_collapsed_sliders) } AnimatedVisibility( modifier = modifier, visible = isExpandable, enter = expandButtonEnterTransition(), exit = expandButtonExitTransition(), ) { PlatformIconButton( modifier = Modifier.size(width = 48.dp, height = 40.dp).semantics { role = Role.Switch stateDescription = expandButtonStateDescription }, onClick = { onExpandedChanged(!isExpanded) }, colors = IconButtonDefaults.iconButtonColors( containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onSurfaceVariant, ), iconResource = if (isExpanded) { R.drawable.ic_arrow_down_24dp } else { R.drawable.ic_arrow_up_24dp }, contentDescription = null, ) } } private fun enterTransition(index: Int, totalCount: Int): EnterTransition { val enterDelay = ((totalCount - index + 1) * 10).coerceAtLeast(0) val enterDuration = (EXPAND_DURATION_MILLIS - enterDelay).coerceAtLeast(100) Loading
packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt +105 −2 Original line number Diff line number Diff line Loading @@ -24,9 +24,18 @@ import androidx.compose.animation.fadeOut import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.getValue Loading @@ -48,6 +57,7 @@ import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.unit.dp import com.android.compose.PlatformSlider import com.android.compose.PlatformSliderColors import com.android.systemui.Flags import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.ui.compose.Icon import com.android.systemui.compose.modifiers.sysuiResTag Loading @@ -61,11 +71,104 @@ import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.Sl fun VolumeSlider( state: SliderState, onValueChange: (newValue: Float) -> Unit, onValueChangeFinished: (() -> Unit)? = null, onIconTapped: () -> Unit, sliderColors: PlatformSliderColors, modifier: Modifier = Modifier, hapticsViewModelFactory: SliderHapticsViewModel.Factory?, onValueChangeFinished: (() -> Unit)? = null, button: (@Composable () -> Unit)? = null, ) { if (!Flags.volumeRedesign()) { LegacyVolumeSlider( state = state, onValueChange = onValueChange, onIconTapped = onIconTapped, sliderColors = sliderColors, onValueChangeFinished = onValueChangeFinished, modifier = modifier, hapticsViewModelFactory = hapticsViewModelFactory, ) return } val value by valueState(state) Column(modifier) { Row( horizontalArrangement = Arrangement.spacedBy(12.dp), modifier = Modifier.fillMaxWidth(), ) { state.icon?.let { Icon( icon = it, tint = MaterialTheme.colorScheme.onSurface, modifier = Modifier.size(40.dp).padding(8.dp), ) } Text( text = state.label, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.weight(1f).align(Alignment.CenterVertically), ) button?.invoke() } Slider( value = value, valueRange = state.valueRange, onValueChange = onValueChange, onValueChangeFinished = onValueChangeFinished, enabled = state.isEnabled, modifier = Modifier.height(40.dp).sysuiResTag(state.label).clearAndSetSemantics { if (state.isEnabled) { contentDescription = state.label state.a11yClickDescription?.let { customActions = listOf( CustomAccessibilityAction(it) { onIconTapped() true } ) } state.a11yStateDescription?.let { stateDescription = it } progressBarRangeInfo = ProgressBarRangeInfo(state.value, state.valueRange) } else { disabled() contentDescription = state.disabledMessage?.let { "${state.label}, $it" } ?: state.label } setProgress { targetValue -> val targetDirection = when { targetValue > value -> 1 targetValue < value -> -1 else -> 0 } val newValue = (value + targetDirection * state.a11yStep).coerceIn( state.valueRange.start, state.valueRange.endInclusive, ) onValueChange(newValue) true } }, ) } } @Composable private fun LegacyVolumeSlider( state: SliderState, onValueChange: (newValue: Float) -> Unit, onIconTapped: () -> Unit, sliderColors: PlatformSliderColors, hapticsViewModelFactory: SliderHapticsViewModel.Factory?, modifier: Modifier = Modifier, onValueChangeFinished: (() -> Unit)? = null, ) { val value by valueState(state) val interactionSource = remember { MutableInteractionSource() } Loading Loading @@ -178,7 +281,7 @@ private fun valueState(state: SliderState): State<Float> { val shouldSkipAnimation = prevState is SliderState.Empty || prevState.isEnabled != state.isEnabled val value = if (shouldSkipAnimation) mutableFloatStateOf(state.value) if (shouldSkipAnimation) remember { mutableFloatStateOf(state.value) } else animateFloatAsState(targetValue = state.value, label = "VolumeSliderValueAnimation") prevState = state return value Loading
packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSliderContent.kt +3 −3 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ private enum class VolumeSliderContentComponent { DisabledMessage, } /** Shows label of the [VolumeSlider]. Also shows [disabledMessage] when not [isEnabled]. */ /** Shows label of the [LegacyVolumeSlider]. Also shows [disabledMessage] when not [isEnabled]. */ @Composable fun VolumeSliderContent( label: String, Loading Loading @@ -89,7 +89,7 @@ fun VolumeSliderContent( } } }, measurePolicy = VolumeSliderContentMeasurePolicy(isEnabled) measurePolicy = VolumeSliderContentMeasurePolicy(isEnabled), ) } Loading @@ -102,7 +102,7 @@ private class VolumeSliderContentMeasurePolicy(private val isEnabled: Boolean) : override fun MeasureScope.measure( measurables: List<Measurable>, constraints: Constraints constraints: Constraints, ): MeasureResult { val labelPlaceable = measurables Loading