Add highlight for sliders and all preference widgets.

Test: Manually on device
Bug: 253536111
Change-Id: I4472d66f741490d00c2ff9bc3c9d41796de34b25
This commit is contained in:
Kelly
2022-10-14 11:11:41 +08:00
parent cd8f204717
commit 949babd7b3
7 changed files with 115 additions and 78 deletions

View File

@@ -17,15 +17,11 @@
package com.android.settingslib.spa.framework.common
import android.os.Bundle
import android.widget.Toast
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.ProvidedValue
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.platform.LocalContext
import com.android.settingslib.spa.framework.compose.LocalNavController
const val INJECT_ENTRY_NAME = "INJECT"
@@ -126,17 +122,6 @@ data class SettingsEntry(
@Composable
fun UiLayout(runtimeArguments: Bundle? = null) {
val context = LocalContext.current
val controller = LocalNavController.current
val highlight = rememberSaveable {
mutableStateOf(controller.highlightEntryId == id)
}
if (highlight.value) {
highlight.value = false
// TODO: Add highlight entry logic
Toast.makeText(context, "entry $id highlighted", Toast.LENGTH_SHORT).show()
}
CompositionLocalProvider(provideLocalEntryData()) {
uiLayoutImpl(fullArgument(runtimeArguments))
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settingslib.spa.framework.util
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.android.settingslib.spa.framework.common.LocalEntryDataProvider
@Composable
internal fun EntryHighlight(UiLayoutFn: @Composable () -> Unit) {
val entryData = LocalEntryDataProvider.current
val isHighlighted = rememberSaveable { entryData.isHighlighted }
val backgroundColor =
if (isHighlighted) MaterialTheme.colorScheme.surfaceVariant else Color.Transparent
Box(modifier = Modifier.background(color = backgroundColor)) {
UiLayoutFn()
}
}

View File

@@ -32,6 +32,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.EntryHighlight
import com.android.settingslib.spa.widget.preference.BaseLayout
import kotlin.math.roundToInt
@@ -108,33 +109,35 @@ fun SettingsSlider(model: SettingsSliderModel) {
internal fun SettingsSlider(
title: String,
initValue: Int,
modifier: Modifier = Modifier,
valueRange: IntRange = 0..100,
onValueChange: ((value: Int) -> Unit)? = null,
onValueChangeFinished: (() -> Unit)? = null,
icon: ImageVector? = null,
showSteps: Boolean = false,
modifier: Modifier = Modifier,
) {
var sliderPosition by rememberSaveable { mutableStateOf(initValue.toFloat()) }
BaseLayout(
title = title,
subTitle = {
Slider(
value = sliderPosition,
onValueChange = {
sliderPosition = it
onValueChange?.invoke(sliderPosition.roundToInt())
},
modifier = modifier,
valueRange = valueRange.first.toFloat()..valueRange.last.toFloat(),
steps = if (showSteps) (valueRange.count() - 2) else 0,
onValueChangeFinished = onValueChangeFinished,
)
},
icon = if (icon != null) ({
Icon(imageVector = icon, contentDescription = null)
}) else null,
)
EntryHighlight {
BaseLayout(
title = title,
subTitle = {
Slider(
value = sliderPosition,
onValueChange = {
sliderPosition = it
onValueChange?.invoke(sliderPosition.roundToInt())
},
modifier = modifier,
valueRange = valueRange.first.toFloat()..valueRange.last.toFloat(),
steps = if (showSteps) (valueRange.count() - 2) else 0,
onValueChangeFinished = onValueChangeFinished,
)
},
icon = if (icon != null) ({
Icon(imageVector = icon, contentDescription = null)
}) else null,
)
}
}
@Preview

View File

@@ -28,26 +28,29 @@ import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.theme.SettingsShape
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.EntryHighlight
@Composable
fun MainSwitchPreference(model: SwitchPreferenceModel) {
Surface(
modifier = Modifier.padding(SettingsDimension.itemPaddingEnd),
color = when (model.checked.value) {
true -> MaterialTheme.colorScheme.primaryContainer
else -> MaterialTheme.colorScheme.secondaryContainer
},
shape = SettingsShape.CornerLarge,
) {
InternalSwitchPreference(
title = model.title,
checked = model.checked,
changeable = model.changeable,
onCheckedChange = model.onCheckedChange,
paddingStart = 20.dp,
paddingEnd = 20.dp,
paddingVertical = 18.dp,
)
EntryHighlight {
Surface(
modifier = Modifier.padding(SettingsDimension.itemPaddingEnd),
color = when (model.checked.value) {
true -> MaterialTheme.colorScheme.primaryContainer
else -> MaterialTheme.colorScheme.secondaryContainer
},
shape = SettingsShape.CornerLarge,
) {
InternalSwitchPreference(
title = model.title,
checked = model.checked,
changeable = model.changeable,
onCheckedChange = model.onCheckedChange,
paddingStart = 20.dp,
paddingEnd = 20.dp,
paddingVertical = 18.dp,
)
}
}
}

View File

@@ -27,6 +27,7 @@ import com.android.settingslib.spa.framework.common.EntrySearchData
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.framework.util.WrapOnClickWithLog
import com.android.settingslib.spa.framework.util.EntryHighlight
import com.android.settingslib.spa.widget.ui.createSettingsIcon
data class SimplePreferenceMacro(
@@ -115,12 +116,14 @@ fun Preference(
)
} else Modifier
}
BasePreference(
title = model.title,
summary = model.summary,
singleLineSummary = singleLineSummary,
modifier = modifier,
icon = model.icon,
enabled = model.enabled,
)
EntryHighlight {
BasePreference(
title = model.title,
summary = model.summary,
singleLineSummary = singleLineSummary,
modifier = modifier,
icon = model.icon,
enabled = model.enabled,
)
}
}

View File

@@ -32,6 +32,7 @@ import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.WrapOnSwitchWithLog
import com.android.settingslib.spa.framework.util.EntryHighlight
import com.android.settingslib.spa.widget.ui.SettingsSwitch
/**
@@ -79,13 +80,15 @@ interface SwitchPreferenceModel {
*/
@Composable
fun SwitchPreference(model: SwitchPreferenceModel) {
InternalSwitchPreference(
title = model.title,
summary = model.summary,
checked = model.checked,
changeable = model.changeable,
onCheckedChange = model.onCheckedChange,
)
EntryHighlight {
InternalSwitchPreference(
title = model.title,
summary = model.summary,
checked = model.checked,
changeable = model.changeable,
onCheckedChange = model.onCheckedChange,
)
}
}
@Composable

View File

@@ -17,6 +17,7 @@
package com.android.settingslib.spa.widget.preference
import androidx.compose.runtime.Composable
import com.android.settingslib.spa.framework.util.EntryHighlight
import com.android.settingslib.spa.widget.ui.SettingsSwitch
@Composable
@@ -25,16 +26,18 @@ fun TwoTargetSwitchPreference(
icon: @Composable (() -> Unit)? = null,
onClick: () -> Unit,
) {
TwoTargetPreference(
title = model.title,
summary = model.summary,
onClick = onClick,
icon = icon,
) {
SettingsSwitch(
checked = model.checked,
changeable = model.changeable,
onCheckedChange = model.onCheckedChange,
)
EntryHighlight {
TwoTargetPreference(
title = model.title,
summary = model.summary,
onClick = onClick,
icon = icon,
) {
SettingsSwitch(
checked = model.checked,
changeable = model.changeable,
onCheckedChange = model.onCheckedChange,
)
}
}
}