在 TextView 中使用区域设置 (ltr/rtl) 作为重力

Posted

技术标签:

【中文标题】在 TextView 中使用区域设置 (ltr/rtl) 作为重力【英文标题】:use locale (ltr/rtl) for gravity in TextView 【发布时间】:2016-03-20 09:48:15 【问题描述】:

我有一个简单的 TextView,它应该有 android:gravity="left" 用于 ltr 系统语言环境,android:gravity="right" 用于 rtl 系统语言环境。

显而易见的选择是:android:gravity="start",然后例如英文文本将始终为左对齐,而希伯来文则为右对齐。

这是android:gravity="start" 的样子:

LTR 语言环境:

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

RTL 语言环境:

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

应该是这样的:

LTR 语言环境:

|לורם           |  
|test            | 

RTL 语言环境:

|          לורם|  
|           test| 

是否可以在不使用带有修改过的 xml 文件的 layout-ldrtl 文件夹的情况下做到这一点?这会使开发变得非常复杂,因为我必须两次编辑大量布局文件......

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

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

因此,如果将此语言环境考虑用于 rtl ltr 选择,那就太好了。

【问题讨论】:

英文文本从左到右呈现我认为是重力启动 是的,这正是我的问题。设置 RTL 语言环境后,是否有强制 RTL 的方法? 试过添加 textdirection 属性吗?但我认为它仅适用于 api 17+ @Bhargav 好建议。如果我将它设置为 android:textDirection="locale" 它与系统区域设置对齐,但不是“应用程序区域设置”,请参阅我的编辑...抱歉造成混淆,我试图简化... 我注意到textDirection 的另一个问题是,如果您使用android:ellipsize 并强制RTL textDirection,“...”将放在左侧,即使是英文...这看起来完全错误。 【参考方案1】:

我也有这个问题,你可以在 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>`

这对我有用。

【讨论】:

谢谢! textDirection 和 textAlignment 对我来说几乎完美! (只有 17 岁以上,但这个问题没问题) textDirection 参数会覆盖默认行为,即基于第一个强字符确定文本方向。这可能会导致意外的错误,例如“你好!”在 RTL 布局方向上显示为“!Hello”。 textAlignment 参数无效,因为它是默认行为。如果你不完全理解它的含义,在使用它之前要小心,在没有适当考虑的情况下覆盖系统的默认行为总是很危险的。 我强烈建议使用另一个答案中提到的textAlignment="viewStart"。这不会导致上述错误。但最好只在本地用于需要这种行为的视图。如果全局使用,这将覆盖所有TextViews 中的gravity 参数,可能会导致UI 错误。【参考方案2】:
android:layout_    
android:textAlignment="viewStart"

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

【讨论】:

谢谢!这是在 match_parent 的情况下工作的唯一答案,用于宽度并以编程方式设置 rtl 语言 确保您的 AndroidManifest.xml 中有 android:supportsRtl="true"。否则,即使在 AS 预览中也无法使用。 这是比覆盖textDirection更好、更安全的解决方案。【参考方案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);
  

【讨论】:

【参考方案4】:

您可能需要一个特殊的扩展 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);
    


... 并在您的布局中使用此类。如果您想即时切换区域设置和所有方向,则需要重新加载布局。

【讨论】:

以上是关于在 TextView 中使用区域设置 (ltr/rtl) 作为重力的主要内容,如果未能解决你的问题,请参考以下文章

用于TextView的Android TextView空白区域长按上下文菜单,而不是文本选择菜单

“Android Utils“ 实现TextView 区域自定义点击

“Android Utils“ 实现TextView 区域自定义点击

“Android Utils“ 实现TextView 区域自定义点击

ScrollView中的TextView - 在键入时禁用自动滚动?

Android学习摘要