基于Jetpack Compose实现的Android Preference
Jetpack Compose实现的Android偏好Preference实现,实现了CheckBoxPreference、EditTextPreference、SingleChoicePreference、SliderPreference等常见的 Preference 类型, 代码如下:
1. 基类Preference :
@Composable
fun Preference(
title: String,
modifier: Modifier = Modifier,
summary: (@Composable () -> Unit)? = null,
control: (@Composable () -> Unit)? = null,
) {
Surface(modifier = modifier) {
Row(
modifier = Modifier.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(2.dp),
) {
Text(
text = title,
style = MaterialTheme.typography.bodyLarge,
)
if (summary != null) {
ProvideTextStyle(
MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant,
),
) {
summary()
}
}
}
control?.invoke()
}
}
}
1. 编辑框 Preference:
@Composable
fun EditTextPreference(
value: String,
onValueChange: (String) -> Unit,
title: String,
modifier: Modifier = Modifier,
summary: String? = null,
placeholder: String = "",
) {
var showDialog by remember { mutableStateOf(false) }
var tempValue by remember { mutableStateOf(value) }
Preference(
title = title,
summary = { if (summary != null) Text(summary) else Text(value) },
modifier = modifier.clickable { showDialog = true }
)
if (showDialog) {
AlertDialog(
onDismissRequest = { showDialog = false },
title = { Text(title) },
text = {
OutlinedTextField(
value = tempValue,
onValueChange = { tempValue = it },
placeholder = { Text(placeholder) },
singleLine = true
)
},
confirmButton = {
TextButton(onClick = {
onValueChange(tempValue)
showDialog = false
}) {
Text("确定")
}
},
dismissButton = {
TextButton(onClick = { showDialog = false }) {
Text("取消")
}
}
)
}
}
1. 单选 Preference:
@Composable
fun SingleChoicePreference(
selectedKey: String,
onSelectionChanged: (String) -> Unit,
title: String,
entries: Map<String, String>,
modifier: Modifier = Modifier,
summary: String? = null,
) {
var showDialog by remember { mutableStateOf(false) }
var tempSelection by remember { mutableStateOf(selectedKey) }
Preference(
title = title,
summary = {
if (summary != null) Text(summary)
else Text(entries[selectedKey] ?: "")
},
modifier = modifier.clickable { showDialog = true }
)
if (showDialog) {
AlertDialog(
onDismissRequest = { showDialog = false },
title = { Text(title) },
text = {
Column {
entries.forEach { (key, value) ->
Row(
Modifier
.fillMaxWidth()
.selectable(
selected = (key == tempSelection),
onClick = { tempSelection = key }
)
.padding(vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = (key == tempSelection),
onClick = null
)
Text(
text = value,
modifier = Modifier.padding(start = 16.dp)
)
}
}
}
},
confirmButton = {
TextButton(onClick = {
onSelectionChanged(tempSelection)
showDialog = false
}) {
Text("确定")
}
},
dismissButton = {
TextButton(onClick = { showDialog = false }) {
Text("取消")
}
}
)
}
}
1. 滑动条 Preference:
@Composable
fun SliderPreference(
value: Float,
onValueChange: (Float) -> Unit,
title: String,
modifier: Modifier = Modifier,
valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
steps: Int = 0,
summary: (Float) -> String = { it.toString() }
) {
Preference(
title = title,
summary = { Text(summary(value)) },
control = {
Slider(
value = value,
onValueChange = onValueChange,
valueRange = valueRange,
steps = steps,
modifier = Modifier.width(150.dp)
)
},
modifier = modifier
)
}
1. 列表 Preference:
@Composable
fun ListPreference(
title: String,
items: List<String>,
onItemSelected: (String) -> Unit,
modifier: Modifier = Modifier,
summary: String? = null
) {
var expanded by remember { mutableStateOf(false) }
Preference(
title = title,
summary = { if (summary != null) Text(summary) },
modifier = modifier.clickable { expanded = true }
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
items.forEach { item ->
DropdownMenuItem(
text = { Text(item) },
onClick = {
onItemSelected(item)
expanded = false
}
)
}
}
}
1. CheckBoxPreference实现代码:
@Composable
fun CheckboxPreference(
checked: Boolean,
onCheckClicked: () -> Unit,
title: String,
modifier: Modifier = Modifier,
summaryOff: String? = null,
summaryOn: String? = null,
) {
Preference(
title = title,
summary = {
if (summaryOff != null && summaryOn != null) {
AnimatedContent(checked) { target ->
Text(text = if (target) summaryOn else summaryOff)
}
} else if (summaryOff != null) {
Text(text = summaryOff)
}
},
control = {
Switch(
checked = checked,
onCheckedChange = { onCheckClicked() },
)
},
modifier = modifier,
)
}
这些实现都基于您提供的 Preference
基础组件,并根据不同类型的 Preference 需求进行了扩展。您可以根据实际需要进一步调整和优化这些组件。
使用这些组件时,您可以像这样在您的设置界面中组合它们:
@Composable
fun SettingsScreen() {
Column {
CheckboxPreference(
checked = true,
onCheckClicked = { /* 处理复选框点击 */ },
title = "启用通知",
summaryOn = "通知已启用",
summaryOff = "通知已禁用"
)
EditTextPreference(
value = "用户名",
onValueChange = { /* 处理用户名更改 */ },
title = "设置用户名",
summary = "点击修改用户名"
)
SingleChoicePreference(
selectedKey = "dark",
onSelectionChanged = { /* 处理主题更改 */ },
title = "选择主题",
entries = mapOf("light" to "浅色", "dark" to "深色", "system" to "跟随系统"),
summary = "选择应用主题"
)
SliderPreference(
value = 0.5f,
onValueChange = { /* 处理音量更改 */ },
title = "音量",
summary = { "当前音量: ${(it * 100).toInt()}%" }
)
ListPreference(
title = "选择语言",
items = listOf("简体中文", "English", "日本語"),
onItemSelected = { /* 处理语言选择 */ },
summary = "选择应用界面语言"
)
}
}
这样,您就可以创建一个功能丰富的设置界面,包含各种类型的 Preference。