Android语言基础教程(141)Android数组(array)资源之使用数组资源:别硬编码了!Android数组资源:让你的App“菜市场”告别杂乱无章!

一、 引子:你那代码,是“杂乱无章”的菜市场吗?

嘿,哥们儿/姐们儿!有没有经历过这种场景:你正在开发一个美食类App,里面有个下拉菜单,需要展示一堆食材。

你二话不说,在Activity里大手一挥:

String[] ingredients = new String[]{"生抽", "老抽", "蚝油", "陈醋", "料酒", "白糖"};

看起来没问题,对吧?功能跑得呼呼的。

但突然,产品经理屁颠屁颠跑过来说:“大佬,我们再加个‘八角’和‘香叶’呗?” 你眉头一皱,找到那行代码,修改,编译,测试… 麻烦。

这还没完!设计师又说:“我们做个英文版吧!” 你当场石化,难道要再写一个String[] ingredients_en = ...?然后用一堆if-else来判断当前语言?

停!打住!

你的代码,此刻就像一个杂乱无章的菜市场:所有的菜品(数据)都胡堆乱放在过道(代码)里。看着就头大,管理起来更是要命。

而今天我要给你安利的Android数组资源,就是那个帮你把菜市场升级成现代化智能超市的“金牌收纳师”!所有商品分门别类,整齐摆放在货架(res/values目录)上,价签清晰(多语言支持),需要时直接按标签取货,优雅,永不过时。

二、 收纳前的准备:为什么要用数组资源?(灵魂拷问)

在请出这位“收纳师”之前,我们先来个灵魂拷问:我凭什么要用它?

  1. 告别“硬编码”,维护性UP! UP! UP!
    把数据写在代码里,就是我们深恶痛绝的“硬编码”。它让数据和你程序的逻辑紧紧耦合在一起。想象一下,如果你的菜名散落在厨房(代码)的各个角落,改个名字你得翻遍整个厨房。而数组资源把数据统一放在res/values目录下的XML文件里,修改数据就像在仓库管理系统中修改库存,一处修改,全局生效。
  2. 国际化(i18n)的“神助攻”
    这是数组资源乃至所有资源文件的杀手锏。你只需要为不同语言创建不同的arrays.xml文件,比如values-en/arrays.xml(英文)和values-zh/arrays.xml(中文)。系统会根据用户手机的语言设置,自动选择对应的数组。你再也不用写那些令人头秃的if (locale.equals("zh")) ...判断句了。
  3. 类型安全与编译时检查
    在XML中定义的资源,Android构建工具会在编译时进行检查。如果格式错了,编译就通不过,直接在开发阶段就把问题揪出来,避免了运行时才崩溃的尴尬。
  4. 资源复用,一劳永逸
    一个数组资源可以在多个Activity、Fragment、甚至布局文件中被复用。定义一次,到处使用。

所以,不用数组资源,就像有洗衣机偏偏要用手搓,不是勤奋,是… 你懂的。

三、 开始收纳!如何定义你的数组资源?(实战演练)

好了,理论说再多不如一行代码。我们的“收纳仓库”就是res/values目录,通常我们会创建一个名为arrays.xml的文件(名字随便起,但顾名思义最好)。

1. 字符串数组 —— 最常用的“蔬菜区”

这绝对是使用频率最高的数组,专门用来存放一串文字信息。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 定义一个名为 “sauces" 的字符串数组,描述常用调味料 -->
    <string-array name="sauces">
        <item>生抽</item>
        <item>老抽</item>
        <item>蚝油</item>
        <item>陈醋</item>
        <item>料酒</item>
        <item>白糖</item>
    </string-array>
    <!-- 定义一个名为 “cuisines" 的字符串数组,描述菜系 -->
    <string-array name="cuisines">
        <item>川菜</item>
        <item>粤菜</item>
        <item>湘菜</item>
        <item>鲁菜</item>
    </string-array>
</resources>

看,是不是像在货架上贴标签、摆商品一样清晰?

2. 整数数组 —— 精准的“称重区”

当你需要存放一些确切的数字时,比如价格(虽然价格通常用plurals)、难度等级、ID列表等,整数数组就派上用场了。

<resources>
    <!-- 定义一个名为 “difficulty_levels” 的整数数组,代表难度等级 -->
    <integer-array name="difficulty_levels">
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>5</item>
        <item>8</item>
    </integer-array>
</resources>

3. 普通数组 / 类型数组 —— 灵活的“综合商品区”

这个稍微不那么常用,但功能强大。它可以存放混合类型?不,你想多了。它其实是TypedArray,主要用于获取@array/以外的资源ID,比如@dimen, @color等。我们最经典的例子就是用它来定义一组颜色。

首先,在colors.xml里定义颜色:

<resources>
    <color name="color_primary">#3F51B5</color>
    <color name="color_primary_dark">#303F9F</color>
    <color name="color_accent">#FF4081</color>
</resources>

然后,在arrays.xml里用<array>把它们组装起来:

<resources>
    <!-- 定义一个名为 “theme_colors” 的普通数组,存放颜色资源 -->
    <array name="theme_colors">
        <item>@color/color_primary</item>
        <item>@color/color_primary_dark</item>
        <item>@color/color_accent</item>
    </array>
</resources>

注意,这里取出来的是一个TypedArray对象,需要特殊处理。

四、 开张营业!如何在代码中调用它们?(终极奥义)

货都上架了,现在顾客(代码)要来买东西了,怎么卖?

场景1:在Activity/Fragment中(Java版)

假设我们有一个Spinner(下拉列表)要显示那些调味料。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 1. 找到Spinner
        Spinner spinnerSauce = findViewById(R.id.spinner_sauce);

        // 2. 【核心】从资源中获取字符串数组
        // getResources().getStringArray(R.array.数组名)
        String[] sauceArray = getResources().getStringArray(R.array.sauces);

        // 3. 创建一个Adapter并设置给Spinner
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, sauceArray);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerSauce.setAdapter(adapter);
    }
}

场景2:在Activity/Fragment中(Kotlin版)

Kotlin让这个过程更加丝滑:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val spinnerSauce: Spinner = findViewById(R.id.spinner_sauce)

        // Kotlin扩展函数,直接resources.getStringArray
        val sauceArray = resources.getStringArray(R.array.sauces)

        val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, sauceArray)
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        spinnerSauce.adapter = adapter
    }
}

场景3:处理整数数组和TypedArray

对于整数数组:

int[] difficultyLevels = getResources().getIntArray(R.array.difficulty_levels);

对于我们刚才定义的theme_colors(TypedArray):

// 获取TypedArray
TypedArray colorArray = getResources().obtainTypedArray(R.array.theme_colors);

// 获取第一个颜色
int firstColor = colorArray.getColor(0, 0); // 0是默认值

// 非常重要!用完后必须回收
colorArray.recycle();

场景4:在布局XML中直接使用!
你没看错,数组资源甚至可以直接在布局文件里使用,最常见的就是给ListViewSpinner设置条目。

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:entries="@array/cuisines" /> <!-- 就是这么简单粗暴! -->

这一行android:entries="@array/cuisines",系统会自动帮你完成我们之前在代码里做的所有Adapter设置工作,非常适合静态数据展示。

五、 走向世界!为数组资源实现国际化

见证奇迹的时刻到了!如何让你的菜市场…啊不,App,支持英文?

  1. res目录下新建一个values-en文件夹(en代表英文)。
  2. 在里面也创建一个arrays.xml文件。
  3. 将内容翻译成英文。

/res/values-en/arrays.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="sauces">
        <item>Light Soy Sauce</item>
        <item>Dark Soy Sauce</item>
        <item>Oyster Sauce</item>
        <item>Vinegar</item>
        <item>Cooking Wine</item>
        <item>Sugar</item>
    </string-array>
    <string-array name="cuisines">
        <item>Sichuan Cuisine</item>
        <item>Cantonese Cuisine</item>
        <item>Hunan Cuisine</item>
        <item>Shandong Cuisine</item>
    </string-array>
</resources>

搞定!当用户手机语言切换为英文时,App会自动加载这个英文版本的数组。是不是魔法?

六、 避坑指南 & 最佳实践
  1. 不要存放复杂对象:数组资源只能存放基本类型(字符串、整数)或资源引用(颜色、尺寸等)。别想着把自定义类对象塞进去。
  2. TypedArray必须回收:用了obtainTypedArray(),就一定要记得recycle(),否则会引起内存问题。
  3. 大型动态数据不适合:如果你的数组数据来自网络,或者非常大且经常变动,那还是老老实实在代码里处理吧。数组资源更适合静态或相对稳定的数据。
  4. 命名规范:给数组起个清晰的名字,比如@array/recipe_steps就比@array/array1好一万倍。
七、 总结

好了,伙计们,我们的“智能超市升级计划”到此就圆满成功了。让我们再回顾一下核心思想:

  • 把数据从代码中“请”出来,放进res/values/arrays.xml这个“中央仓库”。
  • 用好<string-array><integer-array><array> 这三个“货架”,分门别类。
  • 在代码中通过getResources().getXxxArray(R.array.your_array) 这个“取货指令”来优雅地获取数据。
  • 利用不同values-xx目录,轻松实现App的国际化,走向全球。

从今天起,告别那个new String[]{...}的“菜市场时代”,拥抱数组资源这个“智能超市”,让你的代码变得整洁、专业、易于维护。你的未来同事(以及三个月后回头看代码的自己),一定会感谢你今天的这个决定!

快去给你的App来一次彻头彻尾的“大扫除”吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值