如何调整Android 8.0欢迎页语言列表排序
我之前也碰到过一模一样的问题,Android系统在LocalePicker的逻辑里确实会对默认语言(也就是你说的en-US,因为full_base.mk里默认设了这个)做特殊处理——哪怕你手动按自己的顺序加了语言,后面的代码还是会偷偷把它挪到最前面。下面是我当时解决的思路和具体代码修改方案:
1. 定位语言列表的后置调整逻辑
首先你得检查LocalePicker.java里,在调用getAllAssetLocales()之后,有没有对语言列表做调整的代码。通常有两种情况会导致en-US前置:
情况一:默认语言被强制移到首位
在LocalePicker的列表构建方法(比如createLocaleList()或者更新列表的逻辑里),大概率会有类似这样的代码:
Locale defaultLocale = Locale.getDefault(); String defaultLocaleStr = defaultLocale.toString(); int defaultPos = localeList.indexOf(defaultLocaleStr); if (defaultPos > 0) { // 把默认语言移到列表第一位 localeList.remove(defaultPos); localeList.add(0, defaultLocaleStr); }
修改方案:
加个判断,当默认语言是en-US时,跳过这个移动操作:
Locale defaultLocale = Locale.getDefault(); String defaultLocaleStr = defaultLocale.toString(); int defaultPos = localeList.indexOf(defaultLocaleStr); // 只有当默认语言不是en-US时,才执行前置操作 if (defaultPos > 0 && !"en-US".equals(defaultLocaleStr)) { localeList.remove(defaultPos); localeList.add(0, defaultLocaleStr); }
情况二:自定义排序器优先处理en-US
如果代码里用了Collections.sort()并传入了特殊的比较器,比如刻意让en-US排在前面,那你得重写这个排序逻辑。比如原来的代码可能是这样:
Collections.sort(localeList, new Comparator<String>() { @Override public int compare(String l1, String l2) { // 强制让en-US排最前 if ("en-US".equals(l1)) return -1; if ("en-US".equals(l2)) return 1; // 其他语言按字符串排序 return l1.compareTo(l2); } });
修改方案:
要么直接删掉这段排序代码(保持你手动添加的顺序),要么替换成自定义优先级的比较器,比如按你想要的zh-CN、th-TH、vi-VN、my-MM、en-US顺序排序:
final List<String> priorityOrder = Arrays.asList("zh-CN", "th-TH", "vi-VN", "my-MM", "en-US"); Collections.sort(localeList, new Comparator<String>() { @Override public int compare(String l1, String l2) { int idx1 = priorityOrder.indexOf(l1); int idx2 = priorityOrder.indexOf(l2); // 优先按自定义顺序排,不在列表里的语言再按原规则排序 if (idx1 != -1 && idx2 != -1) { return idx1 - idx2; } else if (idx1 != -1) { return -1; } else if (idx2 != -1) { return 1; } else { return l1.compareTo(l2); } } });
2. 检查getAllAssetLocales()内部的默认语言添加逻辑
如果上面的修改还是没效果,那可能getAllAssetLocales()方法本身就先加了en-US。你可以查看这个方法的实现,比如是不是先加了默认语言,再添加其他语言:
// 先添加系统默认语言(en-US) localeList.add(Locale.getDefault().toString()); // 再添加其他语言 localeList.add("zh-CN"); // ...
修改方案:
调整这个方法内的添加顺序,把你想要的语言放在前面,最后再加en-US,同时确保后续没有其他代码再调整顺序。
3. 验证修改效果
改完之后编译测试,打开LocalePicker界面,检查语言列表的顺序是不是符合你预期的:zh-CN → th-TH → vi-VN → my-MM → ... → en-US。
内容的提问来源于stack exchange,提问作者Huang

