You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose M3 TimePicker中实现AM/PM统一大写?

解决Jetpack Compose Material3 TimePicker AM/PM大小写设备差异问题

这个问题源于部分定制ROM(如MIUI)修改了系统Locale的默认日期时间格式化规则,导致Compose的TimePicker组件调用系统API获取AM/PM文本时显示小写,而原生系统环境(如Pixel模拟器)则显示大写。以下是几种可行的解决方法:

方法一:强制自定义AM/PM显示文本

直接绕过系统Locale的格式化,硬编码AM/PM的大写文本,彻底消除设备差异:

import androidx.compose.material3.TimePicker
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.selectable

TimePicker(
    state = rememberTimePickerState(),
    ampmSelector = { isSelected, onClick, ampm ->
        Text(
            text = if (ampm == AmPm.AM) "AM" else "PM",
            modifier = Modifier
                .selectable(
                    selected = isSelected,
                    onClick = onClick,
                    role = Role.RadioButton
                )
                .padding(horizontal = 16.dp, vertical = 12.dp),
            style = if (isSelected) {
                MaterialTheme.typography.titleMedium.copy(color = MaterialTheme.colorScheme.primary)
            } else {
                MaterialTheme.typography.titleMedium
            }
        )
    }
)

这种方法简单直接,完全不受系统ROM的Locale配置影响,和Google Clock应用的处理逻辑一致。

方法二:通过格式化器统一文本大小写

如果希望保留Locale的语言逻辑(比如非英文环境的AM/PM对应文本),但强制统一大小写,可以通过DateTimeFormatter处理后转大写:

import androidx.compose.material3.TimePicker
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.selectable
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoField
import java.util.Locale

TimePicker(
    state = rememberTimePickerState(),
    ampmSelector = { isSelected, onClick, ampm ->
        // 获取当前Locale对应的AM/PM文本后强制转大写
        val ampmText = DateTimeFormatter.ofPattern("a")
            .format(LocalTime.now().with(ChronoField.AMPM_OF_DAY, ampm.ordinal.toLong()))
            .uppercase()
        
        Text(
            text = ampmText,
            modifier = Modifier
                .selectable(
                    selected = isSelected,
                    onClick = onClick,
                    role = Role.RadioButton
                )
                .padding(horizontal = 16.dp, vertical = 12.dp),
            style = if (isSelected) {
                MaterialTheme.typography.titleMedium.copy(color = MaterialTheme.colorScheme.primary)
            } else {
                MaterialTheme.typography.titleMedium
            }
        )
    }
)

这种方法兼顾了Locale的语言适配,同时保证文本大小写统一。

临时方案说明

目前Google官方已收到相关问题反馈,后续可能会在Material3 Compose库的更新中修复该系统ROM兼容性问题。在官方修复前,上述自定义方法可以有效解决设备间的显示差异。

内容的提问来源于stack exchange,提问作者Abhimanyu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:28:20