18、资源管理:字符串、颜色、尺寸、Drawable资源、主题属性引用
资源管理这件事,说实话,是很多初学者容易忽略的「基本功」。我记得刚入行那会儿,觉得把字符串直接写在代码里多方便啊,何必多此一举去建个xml文件?直到后来接手一个项目,需要做多语言适配……嗯,那场面,简直是一场灾难。
今天我们就来系统地聊聊Android资源管理。说白了,就是把那些「可能会变」的东西,从代码里抽出来,放到专门的资源文件里。这样不仅好维护,还能轻松适配不同设备、不同语言。
18.1 字符串资源:不只是文本
字符串资源是最常用的。在res/values/strings.xml里定义,然后在代码或布局中引用。
<!-- res/values/strings.xml -->
<resources>
<string name="app_name">我的应用</string>
<string name="welcome_message">欢迎使用本应用!</string>
<string name="login_hint">请输入用户名和密码</string>
</resources>
在Compose中引用字符串资源,用stringResource()函数:
@Composable
fun Greeting() {
Text(
text = stringResource(R.string.welcome_message)
)
}
<string name="greeting_user">你好,%s!</string>
// 使用时
Text(text = stringResource(R.string.greeting_user, "小明"))
18.2 颜色资源:统一视觉风格
颜色定义在res/values/colors.xml里。一个项目如果没有统一的颜色管理,后期改主题色会让你怀疑人生。
<!-- res/values/colors.xml -->
<resources>
<color name="primary">#FF6200EE</color>
<color name="primary_variant">#FF3700B3</color>
<color name="secondary">#FF03DAC5</color>
<color name="background">#FFFFFFFF</color>
<color name="on_primary">#FFFFFFFF</color>
</resources>
在Compose中,用colorResource()来获取:
@Composable
fun ColoredText() {
Text(
text = "这是主题色",
color = colorResource(R.color.primary)
)
}
MaterialTheme.colors.primary。如果你在用Material Design组件,建议优先用主题颜色,而不是硬编码颜色资源。我曾经在一个项目里混用了两种方式,结果主题切换时颜色乱成一团……
18.3 尺寸资源:适配不同屏幕
尺寸资源放在res/values/dimens.xml里。为什么要用尺寸资源?因为不同屏幕密度下,同样的dp值看起来大小不一样。
<!-- res/values/dimens.xml -->
<resources>
<dimen name="padding_small">8dp</dimen>
<dimen name="padding_medium">16dp</dimen>
<dimen name="padding_large">24dp</dimen>
<dimen name="text_size_title">20sp</dimen>
<dimen name="text_size_body">14sp</dimen>
</resources>
在Compose中,用dimensionResource():
@Composable
fun SizedBox() {
Spacer(
modifier = Modifier
.height(dimensionResource(R.dimen.padding_medium))
.fillMaxWidth()
)
}
18.4 Drawable资源:图片与形状
Drawable资源包括图片(png、jpg、webp)和矢量图(Vector Drawable)。放在res/drawable/目录下。
矢量图在Android中特别推荐使用,因为它缩放不失真,文件还小。用Vector Asset工具可以快速导入Material Icons或SVG文件。
<!-- res/drawable/ic_arrow_back.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
在Compose中加载图片:
@Composable
fun BackIcon() {
Image(
painter = painterResource(R.drawable.ic_arrow_back),
contentDescription = "返回"
)
}
18.5 主题属性引用:动态换肤的利器
主题属性引用,说白了就是「引用当前主题里定义的颜色或样式」。这样当主题切换时,引用的值会自动变化。
在XML布局中,用?attr/语法:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="主题色文字"
android:textColor="?attr/colorPrimary" />
在Compose中,通过MaterialTheme.colors来访问:
@Composable
fun ThemedText() {
Text(
text = "主题色文字",
color = MaterialTheme.colors.primary
)
}
如果你想自定义主题属性,可以这样:
<!-- res/values/attrs.xml -->
<resources>
<attr name="customBackgroundColor" format="color" />
</resources>
然后在主题中赋值:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<item name="customBackgroundColor">#FFE0E0E0</item>
</style>
MaterialTheme的扩展属性。如果你需要自定义主题属性,建议用Compose的CompositionLocal来实现。
18.6 知识体系总览
下面这张图,帮你理清资源管理的整体脉络:
18.7 实战建议
说了这么多,总结几条我自己的经验:
- 字符串一定要用资源文件——哪怕你现在只做中文版。多语言适配时你会感谢自己的。
- 颜色统一管理——定义好主色、辅色、背景色、文字色,别到处写#FFxxxx。
- 尺寸用dp和sp——dp用于布局,sp用于文字。别混用。
- 图片优先用Vector Drawable——除非图片太复杂,否则矢量图是更好的选择。
- 主题属性引用是高级玩法——如果你要做深色模式或换肤,这是必经之路。
好了,资源管理就聊到这里。记住:好的资源管理习惯,能让你少加很多班。
公众号:蓝海资料掘金营,微信deep3321