Loading packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/card/CardPageProvider.kt +27 −10 Original line number Diff line number Diff line Loading @@ -28,7 +28,14 @@ import androidx.compose.material.icons.outlined.Shield import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import com.android.settingslib.spa.framework.common.SettingsEntryBuilder Loading @@ -41,14 +48,14 @@ import com.android.settingslib.spa.gallery.R import com.android.settingslib.spa.widget.card.CardButton import com.android.settingslib.spa.widget.card.CardModel import com.android.settingslib.spa.widget.card.SettingsCard import com.android.settingslib.spa.widget.card.SettingsCollapsibleCard import com.android.settingslib.spa.widget.card.SettingsCardContent import com.android.settingslib.spa.widget.card.SettingsCollapsibleCard import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.scaffold.RegularScaffold object CardPageProvider : SettingsPageProvider { override val name = "CardPage" override val name = "Card" override fun getTitle(arguments: Bundle?) = TITLE Loading Loading @@ -79,10 +86,13 @@ object CardPageProvider : SettingsPageProvider { @Composable private fun SettingsCardWithoutIcon() { var isVisible by rememberSaveable { mutableStateOf(true) } SettingsCard( CardModel( title = stringResource(R.string.sample_title), text = stringResource(R.string.sample_text), isVisible = { isVisible }, onDismiss = { isVisible = false }, buttons = listOf( CardButton(text = "Action") {}, ), Loading @@ -92,21 +102,23 @@ object CardPageProvider : SettingsPageProvider { @Composable fun SampleSettingsCollapsibleCard() { SettingsCollapsibleCard( title = "More alerts", imageVector = Icons.Outlined.Error, models = listOf( val context = LocalContext.current var isVisible0 by rememberSaveable { mutableStateOf(true) } val cards = remember { mutableStateListOf( CardModel( title = stringResource(R.string.sample_title), text = stringResource(R.string.sample_text), title = context.getString(R.string.sample_title), text = context.getString(R.string.sample_text), imageVector = Icons.Outlined.PowerOff, isVisible = { isVisible0 }, onDismiss = { isVisible0 = false }, buttons = listOf( CardButton(text = "Action") {}, ) ), CardModel( title = stringResource(R.string.sample_title), text = stringResource(R.string.sample_text), title = context.getString(R.string.sample_title), text = context.getString(R.string.sample_text), imageVector = Icons.Outlined.Shield, buttons = listOf( CardButton(text = "Action") {}, Loading @@ -114,6 +126,11 @@ object CardPageProvider : SettingsPageProvider { ) ) ) } SettingsCollapsibleCard( title = "More alerts", imageVector = Icons.Outlined.Error, models = cards.toList() ) } Loading packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt +1 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ object SettingsDimension { val itemPaddingAround = 8.dp val itemDividerHeight = 32.dp val iconSmall = 16.dp val iconLarge = 48.dp /** The size when app icon is displayed in list. */ Loading packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/CardModel.kt +9 −0 Original line number Diff line number Diff line Loading @@ -28,5 +28,14 @@ data class CardModel( val title: String, val text: String, val imageVector: ImageVector? = null, val isVisible: () -> Boolean = { true }, /** * A dismiss button will be displayed if this is not null. * * And this callback will be called when user clicks the button. */ val onDismiss: (() -> Unit)? = null, val buttons: List<CardButton> = emptyList(), ) packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCard.kt +49 −9 Original line number Diff line number Diff line Loading @@ -16,28 +16,35 @@ package com.android.settingslib.spa.widget.card import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Close import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.android.settingslib.spa.debug.UiModePreviews import com.android.settingslib.spa.framework.theme.SettingsDimension Loading Loading @@ -87,18 +94,29 @@ fun SettingsCard(model: CardModel) { @Composable internal fun SettingsCardImpl(model: CardModel) { AnimatedVisibility(visible = model.isVisible()) { SettingsCardContent { Column( modifier = Modifier.padding(SettingsDimension.itemPaddingStart), verticalArrangement = Arrangement.spacedBy(SettingsDimension.itemPaddingAround) ) { CardIcon(model.imageVector) CardHeader(model.imageVector, model.onDismiss) SettingsTitle(model.title) SettingsBody(model.text) Buttons(model.buttons) } } } } @Composable fun CardHeader(imageVector: ImageVector?, onDismiss: (() -> Unit)? = null) { Row(Modifier.fillMaxWidth()) { CardIcon(imageVector) Spacer(modifier = Modifier.weight(1f)) DismissButton(onDismiss) } } @Composable private fun CardIcon(imageVector: ImageVector?) { Loading @@ -112,6 +130,28 @@ private fun CardIcon(imageVector: ImageVector?) { } } @Composable private fun DismissButton(onDismiss: (() -> Unit)?) { if (onDismiss == null) return Surface( shape = CircleShape, color = MaterialTheme.colorScheme.secondaryContainer, ) { IconButton( onClick = onDismiss, modifier = Modifier.size(SettingsDimension.itemIconSize) ) { Icon( imageVector = Icons.Outlined.Close, contentDescription = stringResource( androidx.compose.material3.R.string.m3c_snackbar_dismiss ), modifier = Modifier.size(SettingsDimension.iconSmall), ) } } } @Composable private fun Buttons(buttons: List<CardButton>) { if (buttons.isNotEmpty()) { Loading packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCollapsibleCard.kt +1 −1 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ fun SettingsCollapsibleCard( var expanded by rememberSaveable { mutableStateOf(false) } SettingsCard { SettingsCardContent { Header(title, imageVector, models.size, expanded) { expanded = it } Header(title, imageVector, models.count { it.isVisible() }, expanded) { expanded = it } } AnimatedVisibility(expanded) { Column { Loading Loading
packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/card/CardPageProvider.kt +27 −10 Original line number Diff line number Diff line Loading @@ -28,7 +28,14 @@ import androidx.compose.material.icons.outlined.Shield import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import com.android.settingslib.spa.framework.common.SettingsEntryBuilder Loading @@ -41,14 +48,14 @@ import com.android.settingslib.spa.gallery.R import com.android.settingslib.spa.widget.card.CardButton import com.android.settingslib.spa.widget.card.CardModel import com.android.settingslib.spa.widget.card.SettingsCard import com.android.settingslib.spa.widget.card.SettingsCollapsibleCard import com.android.settingslib.spa.widget.card.SettingsCardContent import com.android.settingslib.spa.widget.card.SettingsCollapsibleCard import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.scaffold.RegularScaffold object CardPageProvider : SettingsPageProvider { override val name = "CardPage" override val name = "Card" override fun getTitle(arguments: Bundle?) = TITLE Loading Loading @@ -79,10 +86,13 @@ object CardPageProvider : SettingsPageProvider { @Composable private fun SettingsCardWithoutIcon() { var isVisible by rememberSaveable { mutableStateOf(true) } SettingsCard( CardModel( title = stringResource(R.string.sample_title), text = stringResource(R.string.sample_text), isVisible = { isVisible }, onDismiss = { isVisible = false }, buttons = listOf( CardButton(text = "Action") {}, ), Loading @@ -92,21 +102,23 @@ object CardPageProvider : SettingsPageProvider { @Composable fun SampleSettingsCollapsibleCard() { SettingsCollapsibleCard( title = "More alerts", imageVector = Icons.Outlined.Error, models = listOf( val context = LocalContext.current var isVisible0 by rememberSaveable { mutableStateOf(true) } val cards = remember { mutableStateListOf( CardModel( title = stringResource(R.string.sample_title), text = stringResource(R.string.sample_text), title = context.getString(R.string.sample_title), text = context.getString(R.string.sample_text), imageVector = Icons.Outlined.PowerOff, isVisible = { isVisible0 }, onDismiss = { isVisible0 = false }, buttons = listOf( CardButton(text = "Action") {}, ) ), CardModel( title = stringResource(R.string.sample_title), text = stringResource(R.string.sample_text), title = context.getString(R.string.sample_title), text = context.getString(R.string.sample_text), imageVector = Icons.Outlined.Shield, buttons = listOf( CardButton(text = "Action") {}, Loading @@ -114,6 +126,11 @@ object CardPageProvider : SettingsPageProvider { ) ) ) } SettingsCollapsibleCard( title = "More alerts", imageVector = Icons.Outlined.Error, models = cards.toList() ) } Loading
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt +1 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ object SettingsDimension { val itemPaddingAround = 8.dp val itemDividerHeight = 32.dp val iconSmall = 16.dp val iconLarge = 48.dp /** The size when app icon is displayed in list. */ Loading
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/CardModel.kt +9 −0 Original line number Diff line number Diff line Loading @@ -28,5 +28,14 @@ data class CardModel( val title: String, val text: String, val imageVector: ImageVector? = null, val isVisible: () -> Boolean = { true }, /** * A dismiss button will be displayed if this is not null. * * And this callback will be called when user clicks the button. */ val onDismiss: (() -> Unit)? = null, val buttons: List<CardButton> = emptyList(), )
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCard.kt +49 −9 Original line number Diff line number Diff line Loading @@ -16,28 +16,35 @@ package com.android.settingslib.spa.widget.card import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Close import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.android.settingslib.spa.debug.UiModePreviews import com.android.settingslib.spa.framework.theme.SettingsDimension Loading Loading @@ -87,18 +94,29 @@ fun SettingsCard(model: CardModel) { @Composable internal fun SettingsCardImpl(model: CardModel) { AnimatedVisibility(visible = model.isVisible()) { SettingsCardContent { Column( modifier = Modifier.padding(SettingsDimension.itemPaddingStart), verticalArrangement = Arrangement.spacedBy(SettingsDimension.itemPaddingAround) ) { CardIcon(model.imageVector) CardHeader(model.imageVector, model.onDismiss) SettingsTitle(model.title) SettingsBody(model.text) Buttons(model.buttons) } } } } @Composable fun CardHeader(imageVector: ImageVector?, onDismiss: (() -> Unit)? = null) { Row(Modifier.fillMaxWidth()) { CardIcon(imageVector) Spacer(modifier = Modifier.weight(1f)) DismissButton(onDismiss) } } @Composable private fun CardIcon(imageVector: ImageVector?) { Loading @@ -112,6 +130,28 @@ private fun CardIcon(imageVector: ImageVector?) { } } @Composable private fun DismissButton(onDismiss: (() -> Unit)?) { if (onDismiss == null) return Surface( shape = CircleShape, color = MaterialTheme.colorScheme.secondaryContainer, ) { IconButton( onClick = onDismiss, modifier = Modifier.size(SettingsDimension.itemIconSize) ) { Icon( imageVector = Icons.Outlined.Close, contentDescription = stringResource( androidx.compose.material3.R.string.m3c_snackbar_dismiss ), modifier = Modifier.size(SettingsDimension.iconSmall), ) } } } @Composable private fun Buttons(buttons: List<CardButton>) { if (buttons.isNotEmpty()) { Loading
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCollapsibleCard.kt +1 −1 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ fun SettingsCollapsibleCard( var expanded by rememberSaveable { mutableStateOf(false) } SettingsCard { SettingsCardContent { Header(title, imageVector, models.size, expanded) { expanded = it } Header(title, imageVector, models.count { it.isVisible() }, expanded) { expanded = it } } AnimatedVisibility(expanded) { Column { Loading