在TextView中使用本地化(从左到右/从右到左)以控制重力。

34

我有一个简单的TextView,应该在ltr系统语言环境下具有android:gravity="left",在rtl系统语言环境下具有android:gravity="right"

显然的选择是:android:gravity="start",但这样英文文本将始终左对齐,希伯来文则右对齐。

以下是android:gravity="start"的效果:

LTR语言环境:

|          לורם|   // incorrect
|test           |  // correct

RTL语言环境:

|          לורם|  // correct
|test           |  // incorrect

它应该看起来像这样:

LTR语言环境:

|לורם           |  
|test            | 

RTL语言环境:

|          לורם|  
|           test| 

不使用修改后的xml文件和layout-ldrtl文件夹,是否有可能实现这一点?这将使开发变得更加复杂,因为我必须两次编辑很多布局文件...

编辑: 对于API 17+的解决方案就足够了。我写了系统语言环境,但实际上我允许用户像这样更改应用程序语言:

Configuration configuration = context.getResources().getConfiguration();
configuration.setLayoutDirection(selectedLocale);
configuration.locale = selectedLocale;
context.getResources().updateConfiguration(configuration, context.getResources().getDisplayMetrics());

如果这个语言环境能被考虑在RTL<->LTR的选择中,那就太棒了。


1
英文文本是从左到右呈现的,我认为重力开始。 - Bhargav
1
是的,确实这是我的问题。当RTL语言环境被设置时,有没有一种强制使用RTL的方法? - agrajag
1
尝试添加textdirection属性了吗?但我认为它只适用于API 17+。 - Bhargav
@Bhargav 给出了很好的建议。如果我将其设置为 android:textDirection="locale",它将根据系统区域设置对齐,但不是根据“应用程序区域设置”对齐,可以查看我的编辑... 对于混淆表示抱歉,我试图简化... - agrajag
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - agrajag
5个回答

75

我也遇到了这个问题,你可以使用以下属性来改变TextView的样式

android:textDirection="locale"
android:textAlignment="gravity"

或者将其添加到 styles.xml 中的 Base App Theme 中。

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:textColorPrimary">@android:color/white</item>
    <item name="android:textColorSecondary">@android:color/white</item>
    <item name="colorButtonNormal">@color/colorAccent</item>
    <item name="android:textAlignment">gravity</item>
    <item name="android:textDirection">locale</item>
    </style>`

那对我来说起作用了。

1
谢谢!textDirection和textAlignment对我来说几乎完美!(这只适用于17岁以上的人,但这对这个问题来说没关系) - Louis Tsai
2
textDirection参数覆盖了默认行为,即根据第一个强字符确定文本方向。这可能会导致意外的错误,比如在RTL布局方向下,“Hello!”被显示为“!Hello”。textAlignment参数没有影响,因为它是默认行为。如果您不完全理解其含义,请在使用之前小心考虑,未经妥善考虑地覆盖系统的默认行为始终是危险的。 - Miloš Černilovský
我强烈建议使用在其他答案中提到的textAlignment="viewStart"。这不会导致上述bug。但最好只在需要此行为的视图上本地使用它。如果全局使用,这将覆盖所有TextView中的gravity参数,可能会导致UI bug。 - Miloš Černilovský

43
android:layout_width="match_parent"    
android:textAlignment="viewStart"

如果文本视图被拉伸到父宽度,就不需要改变元素的重力。只需将文本对齐到视图的开始位置,文本将移动到LTR或RTL位置,并与文本内容(希伯来语或西方语言)无关。


3
谢谢!这是唯一一个在宽度为match_parent且以编程方式设置RTL语言的情况下有效的答案。 - mohax
请确保在您的AndroidManifest.xml文件中添加了android:supportsRtl="true"。否则,即使在AS预览中也无法正常工作。 - Egor Neliuba
这比覆盖 textDirection 更好、更安全的解决方案。 - Miloš Černilovský

3

我现在正在使用这个解决方案,虽然我更喜欢简单的XML解决方案,但目前看来这个解决方案非常简约。

if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) {
  if (DynamicLanguage.getLayoutDirection(getContext()) == View.LAYOUT_DIRECTION_RTL) {
    this.textView.setGravity(Gravity.RIGHT);
  } else {
    this.textView.setGravity(Gravity.LEFT);
  }
}

2
您可能需要一个特殊的扩展TextView类来实现这个功能:
public class LocaleAwareTextView extends TextView {
    public LocaleAwareTextView(Context context) {
        super(context);
        setGravity(getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? Gravity.RIGHT : Gravity.LEFT);
    }
    public LocaleAwareTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setGravity(getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? Gravity.RIGHT : Gravity.LEFT);
    }

    public LocaleAwareTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setGravity(getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? Gravity.RIGHT : Gravity.LEFT);
    }

}

...并在您的布局中使用此类。如果您希望动态切换语言和方向,则需要重新加载您的布局。


1

它适用于LTR和RTL文本。如果您希望在阿拉伯语情况下将英语文本设置为RTL,则可以正常工作。

android:textDirection="locale"
android:textAlignment="viewStart"

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