Loading packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt +21 −0 Original line number Diff line number Diff line Loading @@ -20,11 +20,13 @@ import android.os.Bundle import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.DisabledByDefault import androidx.compose.runtime.Composable import androidx.compose.runtime.IntState import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview Loading @@ -33,8 +35,11 @@ import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.theme.SettingsTheme import com.android.settingslib.spa.gallery.R import com.android.settingslib.spa.widget.preference.ListPreferenceModel import com.android.settingslib.spa.widget.preference.ListPreferenceOption import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.RadioPreferences import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.ui.Category import com.android.settingslib.spa.widget.ui.SettingsIcon Loading Loading @@ -103,6 +108,22 @@ object PreferencePageProvider : SettingsPageProvider { override val summary = { ticks.toString() } }) } val selectedId = rememberSaveable { mutableIntStateOf(0) } RadioPreferences( object : ListPreferenceModel { override val title: String = "RadioPreferences" override val options: List<ListPreferenceOption> = listOf( ListPreferenceOption(id = 0, text = "option1"), ListPreferenceOption(id = 1, text = "option2"), ListPreferenceOption(id = 2, text = "option3"), ) override val selectedId: IntState = selectedId override val onIdSelected: (Int) -> Unit = { selectedId.intValue = it } } ) } } Loading packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt +54 −16 Original line number Diff line number Diff line Loading @@ -16,28 +16,34 @@ package com.android.settingslib.spa.widget.preference import androidx.compose.foundation.layout.Column import androidx.compose.foundation.background import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.selection.selectableGroup import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.runtime.Composable import androidx.compose.runtime.IntState import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import com.android.settingslib.spa.framework.compose.thenIf import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.widget.ui.CategoryTitle import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled import com.android.settingslib.spa.widget.ui.Category import com.android.settingslib.spa.widget.ui.SettingsListItem @Composable fun RadioPreferences(model: ListPreferenceModel) { CategoryTitle(title = model.title) Spacer(modifier = Modifier.width(SettingsDimension.itemDividerHeight)) Column(modifier = Modifier.selectableGroup()) { Category(modifier = Modifier.selectableGroup(), title = model.title) { for (option in model.options) { Radio2(option, model.selectedId.intValue, model.enabled()) { model.onIdSelected(it) Loading @@ -54,20 +60,52 @@ fun Radio2( onIdSelected: (id: Int) -> Unit, ) { val selected = option.id == selectedId val surfaceBright = MaterialTheme.colorScheme.surfaceBright Row( modifier = Modifier .fillMaxWidth() modifier = Modifier.fillMaxWidth() .thenIf(isSpaExpressiveEnabled) { Modifier.heightIn(min = SettingsDimension.preferenceMinHeight) .background(surfaceBright) } .selectable( selected = selected, enabled = enabled, onClick = { onIdSelected(option.id) }, role = Role.RadioButton, ) .padding(SettingsDimension.dialogItemPadding), .then( if (isSpaExpressiveEnabled) Modifier.padding(SettingsDimension.itemPadding) else Modifier.padding(SettingsDimension.dialogItemPadding) ), verticalAlignment = Alignment.CenterVertically, ) { RadioButton(selected = selected, onClick = null, enabled = enabled) Spacer(modifier = Modifier.width(SettingsDimension.itemDividerHeight)) Spacer( modifier = Modifier.width( if (isSpaExpressiveEnabled) SettingsDimension.paddingExtraSmall6 else SettingsDimension.itemDividerHeight ) ) SettingsListItem(text = option.text, enabled = enabled) } } @Preview @Composable private fun RadioPreferencePreview() { RadioPreferences( object : ListPreferenceModel { override val title: String = "Title" override val options: List<ListPreferenceOption> = listOf( ListPreferenceOption(id = 0, text = "option1"), ListPreferenceOption(id = 1, text = "option2"), ListPreferenceOption(id = 2, text = "option3"), ) override val selectedId: IntState = remember { mutableIntStateOf(0) } override val onIdSelected: (Int) -> Unit = {} } ) } packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt +3 −3 Original line number Diff line number Diff line Loading @@ -76,7 +76,7 @@ fun CategoryTitle(title: String) { * visually separates groups of items. */ @Composable fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit) { fun Category(title: String? = null, modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit) { var displayTitle by remember { mutableStateOf(false) } Column( modifier = Loading @@ -90,7 +90,7 @@ fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit) if (title != null && displayTitle) CategoryTitle(title = title) Column( modifier = Modifier.onGloballyPositioned { coordinates -> modifier.onGloballyPositioned { coordinates -> displayTitle = coordinates.size.height > 0 } .then( Loading Loading @@ -162,7 +162,7 @@ internal val LocalIsInCategory = compositionLocalOf { false } @Composable private fun CategoryPreview() { SettingsTheme { Category("Appearance") { Category(title = "Appearance") { Preference( object : PreferenceModel { override val title = "Title" Loading packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt +3 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,9 @@ class RadioPreferencesTest { RadioPreferences(remember { object : ListPreferenceModel { override val title = TITLE override val options = emptyList<ListPreferenceOption>() override val options = listOf( ListPreferenceOption(id = 1, text = "A") ) override val selectedId = mutableIntStateOf(0) override val onIdSelected: (Int) -> Unit = {} } Loading Loading
packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt +21 −0 Original line number Diff line number Diff line Loading @@ -20,11 +20,13 @@ import android.os.Bundle import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.DisabledByDefault import androidx.compose.runtime.Composable import androidx.compose.runtime.IntState import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview Loading @@ -33,8 +35,11 @@ import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.theme.SettingsTheme import com.android.settingslib.spa.gallery.R import com.android.settingslib.spa.widget.preference.ListPreferenceModel import com.android.settingslib.spa.widget.preference.ListPreferenceOption import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.RadioPreferences import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.ui.Category import com.android.settingslib.spa.widget.ui.SettingsIcon Loading Loading @@ -103,6 +108,22 @@ object PreferencePageProvider : SettingsPageProvider { override val summary = { ticks.toString() } }) } val selectedId = rememberSaveable { mutableIntStateOf(0) } RadioPreferences( object : ListPreferenceModel { override val title: String = "RadioPreferences" override val options: List<ListPreferenceOption> = listOf( ListPreferenceOption(id = 0, text = "option1"), ListPreferenceOption(id = 1, text = "option2"), ListPreferenceOption(id = 2, text = "option3"), ) override val selectedId: IntState = selectedId override val onIdSelected: (Int) -> Unit = { selectedId.intValue = it } } ) } } Loading
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt +54 −16 Original line number Diff line number Diff line Loading @@ -16,28 +16,34 @@ package com.android.settingslib.spa.widget.preference import androidx.compose.foundation.layout.Column import androidx.compose.foundation.background import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.selection.selectableGroup import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.runtime.Composable import androidx.compose.runtime.IntState import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import com.android.settingslib.spa.framework.compose.thenIf import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.widget.ui.CategoryTitle import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled import com.android.settingslib.spa.widget.ui.Category import com.android.settingslib.spa.widget.ui.SettingsListItem @Composable fun RadioPreferences(model: ListPreferenceModel) { CategoryTitle(title = model.title) Spacer(modifier = Modifier.width(SettingsDimension.itemDividerHeight)) Column(modifier = Modifier.selectableGroup()) { Category(modifier = Modifier.selectableGroup(), title = model.title) { for (option in model.options) { Radio2(option, model.selectedId.intValue, model.enabled()) { model.onIdSelected(it) Loading @@ -54,20 +60,52 @@ fun Radio2( onIdSelected: (id: Int) -> Unit, ) { val selected = option.id == selectedId val surfaceBright = MaterialTheme.colorScheme.surfaceBright Row( modifier = Modifier .fillMaxWidth() modifier = Modifier.fillMaxWidth() .thenIf(isSpaExpressiveEnabled) { Modifier.heightIn(min = SettingsDimension.preferenceMinHeight) .background(surfaceBright) } .selectable( selected = selected, enabled = enabled, onClick = { onIdSelected(option.id) }, role = Role.RadioButton, ) .padding(SettingsDimension.dialogItemPadding), .then( if (isSpaExpressiveEnabled) Modifier.padding(SettingsDimension.itemPadding) else Modifier.padding(SettingsDimension.dialogItemPadding) ), verticalAlignment = Alignment.CenterVertically, ) { RadioButton(selected = selected, onClick = null, enabled = enabled) Spacer(modifier = Modifier.width(SettingsDimension.itemDividerHeight)) Spacer( modifier = Modifier.width( if (isSpaExpressiveEnabled) SettingsDimension.paddingExtraSmall6 else SettingsDimension.itemDividerHeight ) ) SettingsListItem(text = option.text, enabled = enabled) } } @Preview @Composable private fun RadioPreferencePreview() { RadioPreferences( object : ListPreferenceModel { override val title: String = "Title" override val options: List<ListPreferenceOption> = listOf( ListPreferenceOption(id = 0, text = "option1"), ListPreferenceOption(id = 1, text = "option2"), ListPreferenceOption(id = 2, text = "option3"), ) override val selectedId: IntState = remember { mutableIntStateOf(0) } override val onIdSelected: (Int) -> Unit = {} } ) }
packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt +3 −3 Original line number Diff line number Diff line Loading @@ -76,7 +76,7 @@ fun CategoryTitle(title: String) { * visually separates groups of items. */ @Composable fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit) { fun Category(title: String? = null, modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit) { var displayTitle by remember { mutableStateOf(false) } Column( modifier = Loading @@ -90,7 +90,7 @@ fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit) if (title != null && displayTitle) CategoryTitle(title = title) Column( modifier = Modifier.onGloballyPositioned { coordinates -> modifier.onGloballyPositioned { coordinates -> displayTitle = coordinates.size.height > 0 } .then( Loading Loading @@ -162,7 +162,7 @@ internal val LocalIsInCategory = compositionLocalOf { false } @Composable private fun CategoryPreview() { SettingsTheme { Category("Appearance") { Category(title = "Appearance") { Preference( object : PreferenceModel { override val title = "Title" Loading
packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt +3 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,9 @@ class RadioPreferencesTest { RadioPreferences(remember { object : ListPreferenceModel { override val title = TITLE override val options = emptyList<ListPreferenceOption>() override val options = listOf( ListPreferenceOption(id = 1, text = "A") ) override val selectedId = mutableIntStateOf(0) override val onIdSelected: (Int) -> Unit = {} } Loading