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

迁移至Jetpack Compose:如何在Kotlin代码中获取?attrs/属性值

在Jetpack Compose中获取XML里的?attrs/维度值

基础获取方法

对于XML中通过?attr/xxx引用的维度属性,你可以借助LocalContext和obtainStyledAttributes直接在Compose代码中获取:

@Composable
fun ExampleComposable() {
    val context = LocalContext.current
    // 传入要获取的属性ID数组
    val attrs = context.obtainStyledAttributes(intArrayOf(R.attr.your_custom_spacing))
    // 获取维度值(第二个参数是默认值,单位为像素)
    val spacingInPx = attrs.getDimension(0, 0f)
    // 转成Compose的Dp单位
    val spacing = spacingInPx.dp
    // 必须回收StyledAttributes,避免内存泄漏
    attrs.recycle()

    // 直接使用这个值
    Column(modifier = Modifier.padding(spacing)) {
        Text("使用attr定义的间距")
    }
}

全局复用方案(推荐)

如果需要在多个Composable中使用这些属性,最好将其封装到自定义Theme的CompositionLocal中,避免重复代码:

  1. 先定义一个存储维度的类(可选,适合多属性场景):
data class Spacing(
    val small: Dp,
    val medium: Dp,
    val large: Dp
)
  1. 在你的Compose Theme中获取并提供这些属性:
// 定义CompositionLocal
val LocalSpacing = staticCompositionLocalOf {
    Spacing(8.dp, 16.dp, 24.dp) // 默认值
}

@Composable
fun MyAppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val context = LocalContext.current
    // 获取多个attr维度值
    val attrs = context.obtainStyledAttributes(
        intArrayOf(
            R.attr.spacing_small,
            R.attr.spacing_medium,
            R.attr.spacing_large
        )
    )
    val spacing = Spacing(
        small = attrs.getDimension(0, 8.dp.toPx()).dp,
        medium = attrs.getDimension(1, 16.dp.toPx()).dp,
        large = attrs.getDimension(2, 24.dp.toPx()).dp
    )
    attrs.recycle()

    // 其他Theme配置(颜色、排版等)
    val colorScheme = if (darkTheme) darkColorScheme() else lightColorScheme()

    CompositionLocalProvider(
        LocalSpacing provides spacing,
        content = {
            MaterialTheme(
                colorScheme = colorScheme,
                content = content
            )
        }
    )
}
  1. 在任意Composable中直接调用:
@Composable
fun HomeScreen() {
    val spacing = LocalSpacing.current
    Column(
        modifier = Modifier
            .padding(spacing.medium)
            .fillMaxSize()
    ) {
        Text("标题", modifier = Modifier.padding(bottom = spacing.small))
        // ...
    }
}

注意事项

  • 必须调用attrs.recycle()释放资源,否则会造成内存泄漏。
  • getDimension()返回的是像素值,需要通过.dp扩展转成Compose的Dp单位;也可以用LocalDensity.current.run { spacingInPx.toDp() }完成转换。
  • 如果是Material Components的系统属性(比如?attr/actionBarSize),只需替换对应的属性ID即可,例如androidx.appcompat.R.attr.actionBarSize。

内容的提问来源于stack exchange,提问作者Regress.arg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 11:02:45