在搭载Android 8.0的三星设备上,使用RTL格式化"%d - %d"时出现错误

5
我有一个支持RTL的应用程序。在格式化两个团队之间的得分时,我会写类似以下的内容:
t1.setText(String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0));

在Android模拟器上,如果我的textfield设置为textDirection ="locale",那么它会输出“0-1”,在我所有运行Android 8和Android 9的测试设备上,包括我的华为和基本上任何地方。但是,如果我在一个安卓8.0的三星S7上测试这个功能,它会返回“1-0”。我在物理设备上和三星设备实验室进行了测试:https://developer.samsung.com/remotetestlab/rtlDeviceList.action 这是错误的做法吗?当我有一个包含得分的单个文本字段时,如何格式化得分,以便在所有设备的LTR和RTL上都能正常工作?这在大多数设备上都有效,但似乎我在三星设备上错过了某些东西。
下面是我的代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Home team won 1-0"/>

    <TextView
        android:id="@+id/t1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layoutDirection="locale"
        android:text="1-0"
        />
    <TextView
        android:id="@+id/t2"
        android:layoutDirection="rtl"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1-0"
        />
    <TextView
        android:id="@+id/t3"
        android:textDirection="locale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1-0"
        />
    <TextView
        android:textDirection="rtl"
        android:id="@+id/t4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1-0"
        />
    <TextView
        android:textDirection="rtl"
        android:id="@+id/t5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1-0"
        />
    <TextView
        android:textDirection="locale"
        android:id="@+id/t6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1-0"
        />
    <TextView
        android:textDirection="locale"
        android:id="@+id/t7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1-0"
        />
    <TextView
        android:textDirection="locale"
        android:id="@+id/t8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1-0"
        />
    <TextView
        android:textDirection="locale"
        android:id="@+id/t9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1-0"
        />

</LinearLayout>

应用程序代码:
t1.setText(String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0));
t2.setText(String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0));
t3.setText(String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0));
t4.setText(String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0));
t5.setText(String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0));
t6.setText(BidiFormatter.getInstance(Locale.forLanguageTag("ar-MA")).unicodeWrap(String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0), TextDirectionHeuristicsCompat.ANYRTL_LTR));
t7.setText(BidiFormatter.getInstance(Locale.forLanguageTag("ar-MA")).unicodeWrap(String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0), TextDirectionHeuristicsCompat.RTL));
t8.setText("\u200F" + String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0));
t9.setText("ع" + String.format(Locale.forLanguageTag("ar-MA"), "%d - %d", 1, 0));
setSupportActionBar(toolbar);

模拟器截图: enter image description here

三星S7截图: enter image description here


你的手机使用的是哪种语言环境?你是否使用了“强制从右到左布局”开发者选项?如果在setContentView()之前调用Locale.setDefault(getResources().getConfiguration().locale)会发生什么?getResources().getConfiguration()中包含了什么内容?(运行调试器并将输出复制到问题中。我对localelayoutDirection感兴趣。) - Eugen Pechanec
我已经测试了使用ar-MA设置的手机。如果我将其设置为带有东阿拉伯数字的ar-EG,则一切都很好。让我在几分钟内回答其他问题。 - Christer Nordvik
即使使用Locale.setDefault(),我得到了完全相同的结果。从日志语句中可以看出,S7和本地模拟器的结果是相同的:Log.w("RTL", getResources().getConfiguration().locale.toString()); Log.w("RTL", getResources().getConfiguration().locale.toLanguageTag()); Log.w("RTL", getResources().getConfiguration().getLayoutDirection() + "");警告 02-05 22:44:05.423 28972 28972 RTL ar_MA 警告 02-05 22:44:05.423 28972 28972 RTL ar-MA 警告 02-05 22:44:05.423 28972 28972 RTL 1 - Christer Nordvik
我不认为摩洛哥人会用从左到右的阿拉伯语书写... 我只能想到将其归结为 Android 的某个版本。您可以在各种 Android 版本的 Genymotion 模拟器中设置 S7。其他应用程序如何运作?有其他应用程序出现故障或正常工作吗? - Eugen Pechanec
1
@EugenPechanec 我测试了AWS设备农场,这似乎适用于所有三星设备,而所有其他供应商(LG、Google、Motorola、Asus)都能正确显示。所以也许三星有自己的文本小部件导致它出现问题。由于只有在String.format中有两个%d时才会发生这种情况,我想这个错误对我们来说相当独特,我们只需要添加一些丑陋的解决方法 :-/ - Christer Nordvik
2个回答

2

看起来三星设备上的这个bug/功能,在我的情况下可以有一个解决方法:

String RTL_INDICATOR = "\u200f";
t1.setText(String.format(Locale.forLanguageTag("ar-MA"), "%d %s- %d", 1, RTL_INDICATOR, 0));

这个从右到左标记(https://www.fileformat.info/info/unicode/char/200f/index.htm)必须插入在两个整数中间。如果插入在字符串开头,它将无法解决问题。

由于我不得不在多个地方这样做,所以代码变得非常丑陋,但它可以在所有设备上运行,并且在所有Android版本(我测试过的)上都有效,因此暂时将其标记为答案。


-1

添加

     android:layoutDirection="rtl"

到你的

    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"

它没有起作用,请比较代码和第二张图片。 - Eugen Pechanec
是的,这并没有起到任何作用,因为应用程序支持RTL,而语言环境是RTL语言环境。正如我所提到的,在我测试的10多个设备上都运行良好,但在一次使用Android 8.0的三星S7上测试时失败了。 - Christer Nordvik
因为我的大多数应用程序都是阿拉伯语,所以当我遇到相同的问题时,我经常使用它。 - engmms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接