Android 语言切换:硬编码 UI 文本修复实录
Android App 语言切换功能已实现(BaseApplication + attachBaseContext 管道正常),但界面文本硬编码为英文,导致切换语言后 UI 仍显示英文。本文记录 presentation layer 的修复过程。
问题背景
[!bug] 症状描述
语言切换后,底部 Tab 仍然显示HOME、ME,”我的”页面仍然显示Settings、About Us等英文文本。但AppLanguage日志显示stored=zh applied=zh,说明语言切换的核心管道没有问题。
根因:布局文件(XML)和 Kotlin 代码中存在大量硬编码英文字符串,未使用 @string 资源引用,导致语言切换后文本不跟随。

图 1:硬编码文本(左)与资源引用(右)对比
技术分析
Android i18n 架构
Android 的多语言支持依赖 strings.xml 资源文件。正确的实现方式是:
1 | <!-- values/strings.xml --> |
在布局文件中引用:
1 | <TextView android:text="@string/mine_settings" /> |
在 Kotlin 代码中引用:
1 | text = getString(R.string.mine_settings) |
硬编码文本的两大来源
| 来源 | 文件 | 影响 |
|---|---|---|
| 布局文件 | fragment_mine.xml、activity_main.xml 等 |
静态文本,XML 中直接写死 |
| Kotlin 代码 | MainActivity.kt、HistoryActivity.kt、SettingActivity.kt |
运行时动态设置的文本 |
修复方案
[!tip] 修复策略
保持BaseApplication+attachBaseContext语言管道不变,聚焦 presentation layer:添加 32 个本地化字符串资源,替换 8 个布局文件 + 3 个 Kotlin 文件中的硬编码文本。

图 2:修复流程——添加资源 → 替换 XML → 替换 Kotlin 代码
Step 1:添加字符串资源
新增 32 个字符串资源键,覆盖所有硬编码文本:
| 资源文件 | 新增键数 |
|---|---|
values/strings.xml |
32 键(英文默认值) |
values-zh/strings.xml |
32 键(中文翻译) |
values-en/strings.xml |
32 键(英文镜像) |
核心资源键示例:
1 | <!-- Main Tab --> |
Step 2:替换布局文件硬编码文本
| 文件 | 替换数量 |
|---|---|
fragment_mine.xml |
10 处 |
activity_main.xml |
1 处 |
tab_item_badge.xml |
1 处 |
fragment_msg.xml |
1 处 |
activity_about.xml |
1 处 |
activity_histery.xml |
2 处 |
activity_contact.xml |
2 处 |
activity_setting.xml |
7 处 |
修改示例(fragment_mine.xml):
1 | <!-- 修改前 --> |
Step 3:替换 Kotlin 运行时硬编码文本
MainActivity.kt —— Tab 标签列表:
1 | // 修改前 |
HistoryActivity.kt —— Toast 和 Toolbar 文本:
1 | // 修改前 |
SettingActivity.kt —— 对话框文本:
1 | // 修改前 |
验证结果
构建验证
1 | .\gradlew.bat --no-daemon :app:compileDebugKotlin |
USB 真机验证
日志验证(确认语言已正确应用):
1 | AppLanguage: SettingActivity stored=zh applied=zh |
UI Dump 验证(确认中文文本正确显示):
1 | <!-- 切换为中文后 --> |

图 3:真机测试——中文文本正确显示
修改文件汇总
| 文件 | 改动类型 | 说明 |
|---|---|---|
app/src/main/res/values/strings.xml |
新增 | 32 个英文资源键 |
app/src/main/res/values-zh/strings.xml |
新增 | 32 个中文翻译 |
app/src/main/res/values-en/strings.xml |
新增 | 32 个英文镜像 |
fragment_mine.xml |
修改 | 10 处文本替换 |
activity_main.xml |
修改 | 1 处文本替换 |
tab_item_badge.xml |
修改 | 1 处文本替换 |
fragment_msg.xml |
修改 | 1 处文本替换 |
activity_about.xml |
修改 | 1 处文本替换 |
activity_histery.xml |
修改 | 2 处文本替换 |
activity_contact.xml |
修改 | 2 处文本替换 |
activity_setting.xml |
修改 | 7 处文本替换 |
MainActivity.kt |
修改 | Tab 标签运行时本地化 |
HistoryActivity.kt |
修改 | Toast/Toolbar 本地化 |
SettingActivity.kt |
修改 | 对话框文本本地化 |
经验总结
[!warning] 注意事项
- XML 布局文件中的文本也要走资源引用,不能直接写死英文
- Kotlin 代码中动态设置的文本,
List/Array等初始化必须使用getString(R.string.xxx),而非直接硬编码- 资源键命名规范:
{页面}_{功能}_{描述},如mine_settings、history_delete_success
相关文档:
- [[语言切换硬编码UI文本修复/需求分析]](Obsidian 内部链接)
- [[语言切换硬编码UI文本修复/实现方案]]