Android 工具箱之理解 app 资源文件

这是一个系列,我们将其命名为工具箱,如果你还没有看之前的文章:
概要
在 Android 开发中,几乎所有的事情就是资源,而定义资源是你在开发 Android 应用时,最重要的一环。
资源被用在很多地方,例如定义颜色,字符串,图片,布局,菜单等,这样定义的好处就是不再进行硬编码。所有的东西都需要定义在你的资源文件中,然后其被 app 中的 Java 代码所引用。最简单且最常用的资源是 Strings 资源。
资源的分类
下列是 Android 中常用的资源:
-
Property 动画 文件夹:animator 详情:xml 文件定义 Property 动画
-
Tween 动画 文件夹:anim 详情:xml 文件定义 Tween 动画
-
Drawables 文件夹:drawable 详情:bitmap 文件或者 xml 文件
-
Layout 文件夹:layout 详情:用来定义用户界面的 xml 文件
-
Menu 文件夹:menu 详情:用来定义 action bar 或者菜单
-
Values 文件夹:values 详情:用来定义 strings 或者 dimens 等的 xml
完整的,你可以参照 Providing a Resource guide。
定义 String 资源
对于你的应用的每个文本(比如按钮的文本,或者 textview 的文本等),你应该首先在 res/values/strings.xml 文件中定义你的文本。每一个文本都是一对键值对,举个例子,如果你想让你的按钮展示Submit文本,那么你需要在 strings.xml 文件中:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello!</string>
<string name="submit_label">Submit</string>
</resources>
现在如果我引用了资源文件 submit_label,其对应的值 Submit 就会展现。最后,你可以创建多个资源文件针对不同的国家和地区,或者不同的设备。
引用资源
现在我们定义了我们自己的字符串资源,我们可以随时随地的访问它,不论在 Java 代码或者布局文件中。例如,在布局文件中,我们简单的使用@来引用它。
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/submit_label" />
在你的 Java 代码中访问资源文件,你需要使用 getResources.getString 方法或者 getString 方法来通过其资源 id 获取其对应的值。
String submitText = getResources().getString(R.string.submit_label);
相同的方法也适用于图片或者颜色的获取, getResources() 方法返回资源对象,该对象可以获取所有的资源,而每个资源对应一个单独的文件夹。
动态获取资源
在一些例子中,你可能想动态的获取资源。举个栗子:
public String getStringValue(String key) {
// Retrieve the resource id
String packageName = getBaseContext().getPackageName();
Resources resources = getBaseContext().getResources();
int stringId = resources.getIdentifier(key, "string", packageName);
if (stringId == 0) { return null; }
// Return the string value based on the res id
return resources.getString(stringId);
}
现在你可以直接获取资源啦:
public String myKey = "submit_label"; // Maps to R.string.submit_label
public String myStringValue = getStringValue(myKey); // Returns string text
同样的id也可这么做:
// getViewById("tvTest");
public View getViewById(String id) {
// Retrieve the resource id
String packageName = getBaseContext().getPackageName();
Resources resources = getBaseContext().getResources();
int viewId = resources.getIdentifier(id, "id", packageName);
if (viewId == 0) { return null; }
// Return the string value based on the res id
return findViewById(viewId);
}
提供可选择的资源
多样的设计
为了构建杰出的 UI 设计,Android 开发者需要能够让自己的 app 更加广泛的使用在不同的设备上。要这么做,我们首先需要安装屏幕大小区分,app 必须为不同的屏幕设置不同的资源文件。


可选择的资源
资源的强大之处在于其可选择性,基于屏幕大小,分辨率,语言等,通常的资源选择有:
-
针对手机和平板的不同布局文件。
-
针对不同语言的 string 资源。
-
针对不同屏幕分辨率的 drawable 资源。
-
针对不同平台版本的 style 资源。
-
针对不同屏幕方向的布局文件。
针对不同的选择不同的资源文件,我们需要为其创建不同的文件夹,举个栗子,当涉及多个屏幕的时候,我们提供多个图片,那么对应的文件夹应该是 res/drawable-hdpi, res/drawable-xhdpi 和r es/drawable-xxhdpi,系统会根据手机的分辨率自动选择使用哪一张图片,对应的文件树:
res/
drawable/
icon.png
background.png
drawable-hdpi/
icon.png
background.png
理解修饰符
Android 提供了多个修饰符,你可以针对一个文件夹添加多个修饰符。通常情况下:
语言区分:
-
语言区分:en, fr 语言选择
-
屏幕大小:sw480dp,sw600dp 屏幕的最小高度或者宽度
-
屏幕方向:port, land 屏幕处于竖直或者横屏状态
-
屏幕分辨率:hdpi, xhdpi 屏幕分辨率用于选择不同图片
-
平台版本号:v7, v11, v21 平台版本通常用于styles
drawable-en-sw600dp-land 用于英语平板横屏模式。

可选择的布局文件
通常可选择的资源被用来针对不同设备,而布局文件也可有修饰符。举个栗子:
res/
layout/
activity_main.xml
item_photo.xml
layout-sw600dp/
activity_main.xml
layout-sw600dp-land/
activity_main.xml
layout-sw720dp/
activity_main.xml
item_photo.xml
通常来讲,手机在 sw240 和 sw480 之间。7 寸平板为 sw600,10 寸为 sw720。
布局最佳实践
下列为如何确保你的app能够在不同屏幕上展现良好:
-
避免硬编码在你的代码里。
-
尽量使用 RelativeLayout 和不要使用 AbsoluteLayout。
-
使用 wrap_content和match_parent 或者 dp。
-
在需要的适合提供可选择的布局和图片
阅读原文 get Android 工具箱系列内容。
专业的开发者技术社区
多样化线上知识交流
丰富线下活动和给力工作机会

夜雨聆风
