在 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"
。这不会导致上述错误。但最好只在本地用于需要这种行为的视图。如果全局使用,这将覆盖所有TextView
s 中的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 区域自定义点击