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

背景

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

问题

即使有“textDirection”,“layoutDirection”和“gravity”,我找不到相应的通知生成器,即使在兼容性库中也是如此。

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

而不是“X叫Y”,你会得到“Y叫X”(假设“叫”是希伯来语中的一个单词),因为string应该是这样的格式:

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

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

要求是,在希伯来语中,右边的词应该是X,然后是“呼叫”(当然是希伯来语),然后是左边的Y. 正如我试图用英语的例子来表明的,情况正好相反。

我试过了

一个。 我试图search文档,我发现我可能需要重写布局,但这不是一个好的解决scheme。 原因:

  1. 我可能不会使用Android的正确样式。
  2. 下一个Android版本可能会使用不同的样式,这不是未来的certificate。
  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'; } 

C。 我也可以在string中的“1”和“2”之间切换,但是这并不能处理所有的情况,再加上翻译人员更加困惑。

这个问题

有没有办法让通知生成器正确处理文本(对于通知和TickerText)?

任何方式来调整它没有实际做出全新的通知(或更改string)的布局,这可能不是在Android的相同本机样式?

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

Solutions Collecting From Web of "如何处理通知中的混合RTL和LTR语言?"

好的,find一个答案,基于这个这个这个

对于上述情况:

%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()); } } } 

在select使用此解决scheme之前,您还可以检查当前的语言环境是否为RTL。 例:

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

结果:

在这里输入图像说明