Y.S*_*Y.S 15 android locale android-layout android-8.0-oreo
我有一个多语言的应用程序与主要语言英语和第二语言阿拉伯语.
我打电话setLocale()的onCreate()每一个Activity在我的应用程序:
public static void setLocale(Locale locale){
Locale.setDefault(locale);
Context context = MyApplication.getInstance();
final Resources resources = context.getResources();
final Configuration config = resources.getConfiguration();
config.setLocale(locale);
context.getResources().updateConfiguration(config,
resources.getDisplayMetrics());
}
Run Code Online (Sandbox Code Playgroud)
其中locale一个是以下之一:
在调用之前 super.onCreate(savedInstanceState)调用上述方法.
如文档中所述,
android:supportsRtl="true"在清单中添加了.left和right属性start,并end分别.res\values-ar\strings文件夹中,并将可绘制资源放在res\drawable-ar文件夹中(对于其他资源也是如此).以上设置正常.改变后的Locale到ar-AE,阿拉伯文字和资源都正确地显示在我的活动.
但是,对于版本8.0及更高版本的所有Android设备,资源和布局方向都存在问题.
在版本低于8.0的设备上,RTL屏幕正确如下所示:
在所有8.0+的设备上,同样的屏幕看起来像这样:
这是错的.
事实证明,方向和资源都显示不正确.
这里有两个问题:
Locale在应用配置中似乎没有更新正确的内容.关于方向,一种被称为setLayoutDirection()存在的好奇方法,我之前没有注意到.
我想知道这个问题是什么,为什么它发生在奥利奥,它的解决方案是什么.请帮忙/评论一下.
编辑:
根据API差异报告,该
updateConfiguration()方法在Android 7.1(API级别25)中确实已弃用.
另外,找到了所有相关的帖子.按重要性排序:
2. 不推荐使用Android context.getResources.updateConfiguration().
3. 如何更改Android O/Oreo/api 26应用程序语言.
4. 关于区域设置更改的API 24及更高版本中的Android RTL问题
该问题的完整解决方案包括三个步骤:
步骤1:
onCreate()在您的BaseActivity(或您所有的Activity)中,设置如下Locale:
@Override
protected void onCreate(Bundle savedInstanceState) {
// set the Locale the very first thing
Utils.setLocale(Utils.getSavedLocale());
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
......
......
}
Run Code Online (Sandbox Code Playgroud)
其中getSavedLocale()是Locale对应于当前区域的(这将特定于您的项目......)。
该方法Utils.setLocale(...)定义如下:
public static void setLocale(Locale locale){
Context context = MyApplication.getInstance();
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
Locale.setDefault(locale);
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
// updateConfiguration(...) is deprecated in N
if (Build.VERSION.SDK_INT >= 25) {
context = context.getApplicationContext().createConfigurationContext(configuration);
context = context.createConfigurationContext(configuration);
}
context.getResources().updateConfiguration(configuration,
resources.getDisplayMetrics());
}
Run Code Online (Sandbox Code Playgroud)
这Locale在每个Activity. 这对于支持 API 级别 25 的应用程序来说已经足够了。对于 API 级别 26 及以上级别,还需要 STEP 2 和 STEP 3。
第2步:
在您的 中覆盖以下方法BaseActivity:
@Override
protected void attachBaseContext(Context newBase) {
newBase = Utils.getLanguageAwareContext(newBase);
super.attachBaseContext(newBase);
}
Run Code Online (Sandbox Code Playgroud)
其中函数getLanguageAwareContext(...)定义如下:
public static Context getLanguageAwareContext(Context context){
Configuration configuration = context.getResources().getConfiguration();
Locale locale = getIntendedLocale();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
Run Code Online (Sandbox Code Playgroud)
这与第 1 步一起为您的Locale每个Activity应用程序中的 API 级别 26 及更高级别设置正确的值。
然而,正确设置语言方向还需要一步......
步骤 3:
在onCreate()您的 中BaseActivity,添加以下代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
....
....
// yup, it's a legit bug ... :)
if (Build.VERSION.SDK_INT >= 26) {
getWindow().getDecorView().setLayoutDirection(Utils.isRTL()
? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
}
....
....
}
Run Code Online (Sandbox Code Playgroud)
其中isRTL()函数定义如下:
public static boolean isRTL(){
return TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL;
}
Run Code Online (Sandbox Code Playgroud)
上述步骤应该可以解决Locale所有现有 Android 版本上的所有问题(至少涉及设置和文本方向)。
| 归档时间: |
|
| 查看次数: |
1549 次 |
| 最近记录: |