Android语言基础教程(139)Android资源访问之数组(array)资源:别硬编码了!Android数组资源:你的App“弹药库”管理秘籍

嘿,屏幕前的你!是不是经常在写Android代码时,遇到这样的情况:

场景一: 你要做个下拉列表,里面是商品分类。



// 在你的Activity里,你可能会这么写:
String[] categories = new String[]{"数码", "家居", "服饰", "美食", "美妆"};
Spinner spinner = findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, categories);
spinner.setAdapter(adapter);

看起来没问题?但产品经理突然说:“哥,咱们‘美食’改成‘吃货天地’吧,再加个‘图书’分类。”

你咋办?只能灰溜溜地打开Java文件,找到这行代码,修改,重新编译……万一这个数组在好几个地方都用到了呢?想想就头大。

场景二: 你要初始化一堆颜色值或者尺寸值,代码里充斥着
int[] colors = {0xFFAABB, 0xCCDDEE, ...}
。过两天设计师换主题,你又得在代码的海洋里捞针。

停!打住!别再这么“硬刚”代码了!

今天,我要给你安利一个Android开发中超级好用,但却经常被新手忽略的“宝藏男孩”——数组资源

它就像是你App的专属后勤弹药库。所有需要成组出现的数据,都被它安排得井井有条,需要时随时调用,修改时只需动一个地方。这,就是专业开发的范儿!

第一章:为啥要请出“数组资源”这位大神?(优势篇)

解耦之王,维护之光
把数据和代码分离,是优秀程序员的必修课。数组资源帮你把数据统统塞进
res/values/
目录下的XML文件里。UI怎么变,逻辑怎么调,那是Java/Kotlin的事;数据内容是什么,那是XML的事。两者互不干扰,维护起来那叫一个清爽。国际化(i18n)的天然盟友
你的App要出海?支持英文、西班牙文?如果你把字符串数组硬编码在代码里,那你就得准备N份代码。但用了数组资源,你只需要在
res/values-en/

res/values-es/
目录下分别创建同名XML文件,并填写对应的翻译内容。系统会根据用户手机语言,自动选择对应的数组!魔法般的效果!类型安全,IDE好帮手
在XML中定义的数组,在代码中通过
R.array.xxx
来引用。这意味着编译器会帮你检查这个资源ID是否存在。如果你手抖写错了名字,IDE会直接报错,而不是等到运行时才崩溃。这等于上了道保险!性能小贴士
虽然微乎其微,但数组资源在App初始化时会被系统预处理并缓存。相比于每次在代码里
new
一个数组,理论上有一丢丢的效率优势。当然,我们更看重的是前面三条!

第二章:手把手,搭建你的第一个“弹药库”(基础实战篇)

理论吹得天花乱坠,不如一行代码来得实在。走起!

第一步:创建数组资源文件

在你的Android项目里,找到
res/values
目录。通常这里已经有一个
strings.xml
了。我们可以直接在里面加,但为了更规范,我推荐你新建一个文件

右键
values
-> New -> Values Resource File,文件名输入
arrays.xml

现在,你的目录结构看起来应该是这样的:



res/
  values/
    arrays.xml   <-- 新来的!
    strings.xml
    colors.xml
    ...

第二步:编写你的第一个字符串数组

打开
arrays.xml
,它会有一个初始的
<resources>
标签。我们就在里面搞事情。

示例1:定义一个商品分类数组



<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 字符串数组,name属性是你给它起的名字,调用时就靠它 -->
    <string-array name="product_categories">
        <item>全部商品</item>
        <item>数码电子</item>
        <item>家居生活</item>
        <item>潮服穿搭</item>
        <item>吃货天地</item> <!-- 看,产品经理让改的“美食”变“吃货天地”了,轻松! -->
        <item>图书文创</item> <!-- 新增的“图书”分类 -->
    </string-array>
</resources>

看,如果产品经理再想改,你只需要打开这个文件,动动手指,保存。所有用到这个
product_categories
的地方,内容全都自动更新了!是不是爽翻了?

第三步:在代码中调用“弹药”

弹药装填完毕,现在该上战场了。我们回到最初的Spinner例子。



public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        Spinner spinner = findViewById(R.id.spinner);
 
        // 关键代码在这里!!!
        // 使用 resources.getStringArray() 并传入数组资源的ID:R.array.你的数组名
        String[] categoriesFromResources = getResources().getStringArray(R.array.product_categories);
 
        // 然后用这个从资源里加载的数组创建Adapter
        ArrayAdapter<String> adapter = new ArrayAdapter<>(
                this,
                android.R.layout.simple_spinner_item,
                categoriesFromResources // 这里传入的是从资源读取的数组
        );
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
    }
}

运行一下,你的下拉列表是不是完美出现了?而且修改
arrays.xml
里的
<item>
,App界面会同步变化,无需改动任何Java代码!

第三章:不止是字符串!你的“弹药”多种多样(进阶篇)

你以为“弹药库”里只有“字符串”这一种子弹?Naive!它可是个多面手。

1. 整数数组

比如,你要定义一个页面切换的动画时长序列,或者一组特殊的颜色值(虽然颜色更推荐用
colors.xml
)。



<!-- 在arrays.xml中 -->
<integer-array name="animation_durations">
    <item>100</item>
    <item>300</item>
    <item>500</item>
</integer-array>

代码中调用:


int[] durations = getResources().getIntArray(R.array.animation_durations);

2. 其他类型 & 混合型(骚操作)

Android官方主要支持
string-array

integer-array
。但有时候我们就是需要放一些其他东西,比如
Drawable
的ID怎么办?

技巧:用“资源ID引用”数组

我们可以定义一个数组,里面的每个
item
都是对另一个资源的引用。



<!-- 定义一组图标资源ID的数组 -->
<array name="tab_icons">
    <item>@drawable/ic_home</item> <!-- 引用drawable资源 -->
    <item>@drawable/ic_discover</item>
    <item>@drawable/ic_me</item>
</array>
<!-- 甚至,可以混合引用不同类型! -->
<array name="mixed_bag">
    <item>@string/app_name</item> <!-- 引用字符串 -->
    <item>@color/primary</item>   <!-- 引用颜色 -->
    <item>@dimen/activity_padding</item> <!-- 引用尺寸 -->
</array>

在代码中获取这种数组时,你得到的是一个
TypedArray
,需要手动解析每个元素的类型。



TypedArray typedArray = getResources().obtainTypedArray(R.array.tab_icons);
// 获取第一个元素(一个Drawable)
Drawable firstTabIcon = typedArray.getDrawable(0);
// ... 用完一定要回收!
typedArray.recycle();

这个
TypedArray
用起来稍微麻烦点,但功能极其强大,是实现复杂UI(如底部导航栏同时设置图标和文字)的利器。

第四章:实战!在布局XML中直接使用数组(装X篇)

谁说数组只能在代码里用?在布局XML里,我们也能直接把它绑定到一些控件上,比如
<ListView>

entries
属性。

示例:用数组快速填充一个静态列表


activity_main.xml
中:



<ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:entries="@array/product_categories" /> <!-- 就是这一行! -->

看到了吗?只需要一行
android:entries="@array/product_categories"
,ListView就会自动显示我们之前在
arrays.xml
里定义的所有分类项。连Adapter都不用写!对于简单的、静态的列表,这简直是神器!

第五章:完整示例代码(抄作业专区)

怕你忘了,这里给你一份完整的、可以直接复制粘贴运行的示例代码。

1.
res/values/arrays.xml



<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="product_categories">
        <item>全部商品</item>
        <item>数码电子</item>
        <item>家居生活</item>
        <item>潮服穿搭</item>
        <item>吃货天地</item>
        <item>图书文创</item>
    </string-array>
    <integer-array name="demo_integers">
        <item>1</item>
        <item>2</item>
        <item>3</item>
    </integer-array>
</resources>

2.
res/layout/activity_main.xml



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="下拉列表示例(代码中加载)"
        android:textStyle="bold" />
 
    <Spinner
        android:id="@+id/mySpinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp" />
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="列表视图示例(XML中直接绑定)"
        android:textStyle="bold"
        android:layout_marginTop="32dp" />
 
    <ListView
        android:id="@+id/myListView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/product_categories" />
 
</LinearLayout>

3.
MainActivity.java



public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // 1. 演示在代码中加载字符串数组到Spinner
        Spinner spinner = findViewById(R.id.mySpinner);
        String[] categories = getResources().getStringArray(R.array.product_categories);
        ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, categories);
        spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(spinnerAdapter);
 
        // 2. 演示获取整数数组
        int[] numbers = getResources().getIntArray(R.array.demo_integers);
        for (int num : numbers) {
            Log.d("ArrayDemo", "整数: " + num);
        }
 
        // 3. ListView已经在XML中通过 android:entries 绑定了,所以这里什么都不用做!
    }
}

总结

好啦,兄弟!关于Android数组资源的深度之旅就到这儿。

我们从头到尾捋了一遍:

为什么用? -> 为了代码干净、好维护、能国际化怎么用? ->
arrays.xml
里定义
<string-array>

<integer-array>
,然后在代码里用
getResources().getXXXArray(R.array.xxx)
调用有啥高级的? ->
<array>
存放资源引用,甚至混合类型,用
TypedArray
解析有啥捷径? -> 在布局XML里直接用
@array/xxx
绑定到控件的
entries
属性

从今往后,请彻底告别那些散落在代码各处的硬编码数组吧!把它们统统收进“数组资源”这个高级定制的弹药库里。你的代码会变得更优雅,你也会显得更专业。

这波操作,你学会了吗?赶紧打开Android Studio,试试看!

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
嘿喽Nice的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容