diff options
| author | 2025-02-28 13:22:31 +0000 | |
|---|---|---|
| committer | 2025-03-05 10:56:08 +0000 | |
| commit | d88f8f54e31c6e4e01d2f73f7167d4f1d3481864 (patch) | |
| tree | 80de3eaf456e6726c46f43536cd62ffea129df1a | |
| parent | 7fd9e92e8d4be963a3fe2608b7d563abfebb0c39 (diff) | |
Reorganize activity chip so only the chip itself animates.
In the previous setup, the whole tap target animated, causing it to
look weird and flicker in some cases.
Also drive-by fix to clip interaction ripples correctly to the chip.
Bug: 202516970
Fix: 397505143
Flag: com.android.systemui.status_bar_chips_modernization
Test: manual, see before and after in the bug
Change-Id: I7917c395612bbabc330efb9d28c707cff7eebbfe
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt | 174 |
1 files changed, 66 insertions, 108 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt index d81ea07cae2d..4edb23dc9f0e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt @@ -18,24 +18,18 @@ package com.android.systemui.statusbar.chips.ui.compose import android.content.res.ColorStateList import android.view.ViewGroup -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape import androidx.compose.ui.layout.layout import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource @@ -43,7 +37,6 @@ import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.viewinterop.AndroidView import com.android.compose.animation.Expandable -import com.android.compose.modifiers.thenIf import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.compose.Icon import com.android.systemui.common.ui.compose.load @@ -60,32 +53,45 @@ fun OngoingActivityChip( iconViewStore: NotificationIconContainerViewBinder.IconViewStore?, modifier: Modifier = Modifier, ) { - when (val clickBehavior = model.clickBehavior) { - is OngoingActivityChipModel.ClickBehavior.ExpandAction -> { - // Wrap the chip in an Expandable so we can animate the expand transition. - ExpandableChip( - color = { Color.Transparent }, - shape = - RoundedCornerShape( - dimensionResource(id = R.dimen.ongoing_activity_chip_corner_radius) - ), - modifier = modifier, - ) { expandable -> - ChipBody(model, iconViewStore, onClick = { clickBehavior.onClick(expandable) }) - } + val contentDescription = + when (val icon = model.icon) { + is OngoingActivityChipModel.ChipIcon.StatusBarView -> icon.contentDescription.load() + is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon -> + icon.contentDescription.load() + is OngoingActivityChipModel.ChipIcon.SingleColorIcon, + null -> null } - is OngoingActivityChipModel.ClickBehavior.ShowHeadsUpNotification -> { - ChipBody( - model, - iconViewStore, - onClick = { clickBehavior.onClick() }, - modifier = modifier, - ) + + val borderStroke = + model.colors.outline(LocalContext.current)?.let { + BorderStroke(dimensionResource(R.dimen.ongoing_activity_chip_outline_width), Color(it)) } - is OngoingActivityChipModel.ClickBehavior.None -> { - ChipBody(model, iconViewStore, modifier = modifier) + val onClick = + when (val clickBehavior = model.clickBehavior) { + is OngoingActivityChipModel.ClickBehavior.ExpandAction -> { expandable: Expandable -> + clickBehavior.onClick(expandable) + } + is OngoingActivityChipModel.ClickBehavior.ShowHeadsUpNotification -> { _ -> + clickBehavior.onClick() + } + is OngoingActivityChipModel.ClickBehavior.None -> null } + + Expandable( + color = Color(model.colors.background(LocalContext.current).defaultColor), + shape = + RoundedCornerShape(dimensionResource(id = R.dimen.ongoing_activity_chip_corner_radius)), + modifier = + modifier.height(dimensionResource(R.dimen.ongoing_appops_chip_height)).semantics { + if (contentDescription != null) { + this.contentDescription = contentDescription + } + }, + borderStroke = borderStroke, + onClick = onClick, + ) { + ChipBody(model, iconViewStore, isClickable = onClick != null) } } @@ -93,22 +99,13 @@ fun OngoingActivityChip( private fun ChipBody( model: OngoingActivityChipModel.Active, iconViewStore: NotificationIconContainerViewBinder.IconViewStore?, + isClickable: Boolean, modifier: Modifier = Modifier, - onClick: (() -> Unit)? = null, ) { - val context = LocalContext.current - val isClickable = onClick != null val hasEmbeddedIcon = model.icon is OngoingActivityChipModel.ChipIcon.StatusBarView || model.icon is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon - val contentDescription = - when (val icon = model.icon) { - is OngoingActivityChipModel.ChipIcon.StatusBarView -> icon.contentDescription.load() - is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon -> - icon.contentDescription.load() - is OngoingActivityChipModel.ChipIcon.SingleColorIcon -> null - null -> null - } + val chipSidePadding = dimensionResource(id = R.dimen.ongoing_activity_chip_side_padding) val minWidth = if (isClickable) { @@ -119,68 +116,38 @@ private fun ChipBody( dimensionResource(id = R.dimen.ongoing_activity_chip_min_text_width) + chipSidePadding } - val outline = model.colors.outline(context) - val outlineWidth = dimensionResource(R.dimen.ongoing_activity_chip_outline_width) - - val shape = - RoundedCornerShape(dimensionResource(id = R.dimen.ongoing_activity_chip_corner_radius)) - - // Use a Box with `fillMaxHeight` to create a larger click surface for the chip. The visible - // height of the chip is determined by the height of the background of the Row below. - Box( - contentAlignment = Alignment.Center, + Row( + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, modifier = modifier .fillMaxHeight() - .clickable(enabled = isClickable, onClick = onClick ?: {}) - .semantics { - if (contentDescription != null) { - this.contentDescription = contentDescription - } - }, - ) { - Row( - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - modifier = - Modifier.height(dimensionResource(R.dimen.ongoing_appops_chip_height)) - .thenIf(isClickable) { Modifier.widthIn(min = minWidth) } - .layout { measurable, constraints -> - val placeable = measurable.measure(constraints) - layout(placeable.width, placeable.height) { - if (constraints.maxWidth >= minWidth.roundToPx()) { - placeable.place(0, 0) - } + .layout { measurable, constraints -> + val placeable = measurable.measure(constraints) + layout(placeable.width, placeable.height) { + if (constraints.maxWidth >= minWidth.roundToPx()) { + placeable.place(0, 0) } } - .background(Color(model.colors.background(context).defaultColor), shape = shape) - .thenIf(outline != null) { - Modifier.border( - width = outlineWidth, - color = Color(outline!!), - shape = shape, - ) - } - .padding( - horizontal = - if (hasEmbeddedIcon) { - dimensionResource( - R.dimen - .ongoing_activity_chip_side_padding_for_embedded_padding_icon - ) - } else { - dimensionResource(id = R.dimen.ongoing_activity_chip_side_padding) - } - ), - ) { - model.icon?.let { - ChipIcon(viewModel = it, iconViewStore = iconViewStore, colors = model.colors) - } + } + .padding( + horizontal = + if (hasEmbeddedIcon) { + dimensionResource( + R.dimen.ongoing_activity_chip_side_padding_for_embedded_padding_icon + ) + } else { + dimensionResource(id = R.dimen.ongoing_activity_chip_side_padding) + } + ), + ) { + model.icon?.let { + ChipIcon(viewModel = it, iconViewStore = iconViewStore, colors = model.colors) + } - val isIconOnly = model is OngoingActivityChipModel.Active.IconOnly - if (!isIconOnly) { - ChipContent(viewModel = model) - } + val isIconOnly = model is OngoingActivityChipModel.Active.IconOnly + if (!isIconOnly) { + ChipContent(viewModel = model) } } } @@ -228,6 +195,7 @@ private fun StatusBarIcon( iconFactory: () -> StatusBarIconView?, ) { val context = LocalContext.current + val colorTintList = ColorStateList.valueOf(colors.text(context)) val iconSizePx = context.resources.getDimensionPixelSize( @@ -238,18 +206,8 @@ private fun StatusBarIcon( factory = { _ -> iconFactory.invoke()?.apply { layoutParams = ViewGroup.LayoutParams(iconSizePx, iconSizePx) - imageTintList = ColorStateList.valueOf(colors.text(context)) } ?: throw IllegalStateException("Missing StatusBarIconView for $notificationKey") }, + update = { iconView -> iconView.imageTintList = colorTintList }, ) } - -@Composable -private fun ExpandableChip( - color: () -> Color, - shape: Shape, - modifier: Modifier = Modifier, - content: @Composable (Expandable) -> Unit, -) { - Expandable(color = color(), shape = shape, modifier = modifier.clip(shape)) { content(it) } -} |