android - 如何在通知中处理混合的 RTL 和 LTR 语言?

标签 android android-notifications android-support-library hebrew rtl-language

背景

Android 4.3 增加了大量对 RTL(从右到左)语言的支持,例如希伯来语和阿拉伯语。

问题

即使有“textDirection”、“layoutDirection”和“gravity”,我也找不到通知生成器的等效项,甚至在兼容性库中也找不到。

这意味着如果希伯来语和英语单词在一起,顺序是错误的。 例如(为了简单起见,我用英文写):

您得到的不是“X called Y”,而是“Y called X”(假设“called”是希伯来语中的一个词),因为字符串应该采用以下格式:

<string name="notification">%1$s called %2$s</string>

注意:X 和 Y 可以是 RTL 或 LTR 字(甚至是数字)。

要求是在希伯来语中,右边的单词应该是 X ,然后是单词“called”(当然是希伯来语),然后是左边的 Y。正如我在英语类比示例中试图展示的那样,它恰恰相反。

我尝试过的

一个。我试图搜索文档,但我发现的只是我可能需要覆盖布局,但这不是一个好的解决方案。原因:

  1. 我可能没有使用正确的 Android 样式。
  2. 这不是下一个 Android 版本的 future 证明,可能会使用不同的样式。
  3. 不支持代码文本。

我还尝试调查哪些特殊字符会强制文本方向不同,并且通过在文本的开头和结尾添加 '\u200f' 来显示,但它有一些缺陷:

  1. 它不像其他属性那样灵活。
  2. 我不确定我是否使用官方方式来处理这个问题。
  3. 我每次使用通知时都需要添加这个
  4. 它对 tickerText 根本不起作用。仅适用于通知,即便如此,也并非适用于所有情况。

这是一个示例代码:

/** prepares a string to be shown in a notification, so that it will be shown even on RTL languages */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static String prepareNotificationText(final Context context, final String text) {
    if (VERSION.SDK_INT < VERSION_CODES.JELLY_BEAN_MR1)
        return text;
    final boolean isRTL = context.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
    if (!isRTL)
        return text;
    return '\u200f' + text + '\u200f';
}

我也可以在字符串中的“1”和“2”之间切换,但这并不能处理所有情况,而且它会让翻译人员更加困惑。

问题

有什么方法可以让通知生成器正确处理文本(对于通知和 TickerText)?

有什么方法可以调整它,而无需真正为通知(或更改字符串)制作全新的布局,这可能与 Android 的原生风格不同?

处理这种事情的官方方式是什么?

最佳答案

好的,找到答案,基于this , thisthis .

对于上述情况:

%1$s 调用了 %2$s

为了将其正确更改为希伯来语,您需要添加特殊字符“\u200f”,如下所示:

  <string name="notification">%1$s התקשר ל %2$s</string>


    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    if (VERSION.SDK_INT >= VERSION_CODES.O) {
        String id = "my_channel_01";
        CharSequence name = "channelName";// getString(R.string.channel_name);
        String description = "channelDesc";//getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_LOW;
        NotificationChannel channel = new NotificationChannel(id, name, importance);
        channel.setDescription(description);
        channel.enableLights(true);
        channel.setLightColor(Color.RED);
        channel.enableVibration(true);
        channel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
        notificationManager.createNotificationChannel(channel);
    }
    Intent resultIntent = new Intent(this, MainActivity.class);
    PendingIntent resultPendingIntent =
            PendingIntent.getActivity(
                    this,
                    0,
                    resultIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT
            );

    String[] names1 = new String[]{"משה", "Moses"};
    String[] names2 = new String[]{"דוד", "David"};
    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 2; ++j) {
            String name1, name2;
            name1 = names1[i];
            name2 = names2[j];
            name1 = "\u200f" + name1 + "\u200f";
            name2 = "\u200f" + name2 + "\u200f";

            final String text = getString(R.string.notification, name1, name2);
            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(this, "TEST")
                            .setSmallIcon(R.mipmap.ic_launcher)
                            .setContentTitle(text)
                            .setContentIntent(resultPendingIntent)
                            .setChannelId("my_channel_01")
                            .setContentText(text);
            int notificationId = i*2+j;
            notificationManager.notify(notificationId, mBuilder.build());
        }
    }
}

在选择使用此解决方案之前,您还可以检查当前语言环境是否为 RTL。示例:

public static boolean isRTL() {
    return
            Character.getDirectionality(Locale.getDefault().getDisplayName().charAt(0)) ==
                    Character.DIRECTIONALITY_RIGHT_TO_LEFT;
}

结果:

enter image description here

关于android - 如何在通知中处理混合的 RTL 和 LTR 语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25976440/

相关文章:

android - 如何单击工具栏后面的 View ?

android - 为什么 Android Studio 强制使用 Android 支持库中的 Androidx?

java - 使用php和java进行密码加密

java - 从命令行运行gradle时如何将自定义JAR文件添加到CLASSPATH?

java - Android中用于wifi-usb的任何第三方打印SDK库

android - GCM 推送通知大图标大小

android - 如何访问另一个 Android 应用程序的通知 channel ?

android - 如何控制通知组点击

java - SeekBar 用于录制 30 秒声音 - handlerReceiveCallback 错误

java - 更改向上箭头颜色后标记为私有(private)警告