基于Jetpack Compose实现的Android Preference

科技   2024-07-11 09:37   浙江  

基于Jetpack Compose实现的Android Preference

Jetpack Compose实现的Android偏好Preference实现,实现了CheckBoxPreference、EditTextPreference、SingleChoicePreference、SliderPreference等常见的 Preference 类型, 代码如下:

  1. 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. 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. 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. 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. 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. 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。

虎哥Lovedroid
Android技术达人 近10年一线开发经验 关注并分享Android、Kotlin新技术,新框架 多年Android底层框架修改经验,对Framework、Server、Binder等架构有深入理解
 最新文章