请考虑以下片段:
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:text="StrangerThings"/>
Java方面
TextView tv =findViewById(R.id.tv);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tv.getLayoutParams();
params.setMarginStart(0);
在Android Manifest中将supportRTL标志设置为true时,上面的代码按预期产生的页边距为0。但是,如果supportsRTL为false,则setMarginStart无效。
此外,如果SupportsRTL为false,则无论您如何设置左边界(在xml中或以编程方式使用setMargins),一旦设置了左边界,setMarginStart都不会对其起作用。
这是预期的android行为还是错误?有人可以解释这种行为吗?
答案 0 :(得分:0)
tl; dr -android:supportsRtl="false"
将应用置于“ RTL兼容模式”,这在定义了startMargin
的任何情况下都会导致leftMargin
被忽略。删除android:layout_marginLeft="50dp"
属性可使startMargin
生效。
在MarginLayoutParams
类中,两个不同的字段跟踪“左边”边距和“开始”边距(它们具有非常有创意的名称:leftMargin
和startMargin
)。类似地,两个不同的字段跟踪“右”边距和“结束”边距。
该类几乎使用“左”和“右”边距完成所有工作;它只是经历了一个将“开始”和“结束”值(基于布局方向)解析为“左”或“右”的过程。这是该方法的源代码:
private void doResolveMargins() {
if ((mMarginFlags & RTL_COMPATIBILITY_MODE_MASK) == RTL_COMPATIBILITY_MODE_MASK) {
// if left or right margins are not defined and if we have some start or end margin
// defined then use those start and end margins.
if ((mMarginFlags & LEFT_MARGIN_UNDEFINED_MASK) == LEFT_MARGIN_UNDEFINED_MASK
&& startMargin > DEFAULT_MARGIN_RELATIVE) {
leftMargin = startMargin;
}
if ((mMarginFlags & RIGHT_MARGIN_UNDEFINED_MASK) == RIGHT_MARGIN_UNDEFINED_MASK
&& endMargin > DEFAULT_MARGIN_RELATIVE) {
rightMargin = endMargin;
}
} else {
// We have some relative margins (either the start one or the end one or both). So use
// them and override what has been defined for left and right margins. If either start
// or end margin is not defined, just set it to default "0".
switch(mMarginFlags & LAYOUT_DIRECTION_MASK) {
case View.LAYOUT_DIRECTION_RTL:
leftMargin = (endMargin > DEFAULT_MARGIN_RELATIVE) ?
endMargin : DEFAULT_MARGIN_RESOLVED;
rightMargin = (startMargin > DEFAULT_MARGIN_RELATIVE) ?
startMargin : DEFAULT_MARGIN_RESOLVED;
break;
case View.LAYOUT_DIRECTION_LTR:
default:
leftMargin = (startMargin > DEFAULT_MARGIN_RELATIVE) ?
startMargin : DEFAULT_MARGIN_RESOLVED;
rightMargin = (endMargin > DEFAULT_MARGIN_RELATIVE) ?
endMargin : DEFAULT_MARGIN_RESOLVED;
break;
}
}
mMarginFlags &= ~NEED_RESOLUTION_MASK;
}
当清单设置为android:supportsRtl="false"
时,我们进入顶部if
语句的第一分支。因此,现在的问题是,左边距是否为“未定义” ...,并且我们知道不是,因为视图标记指定了android:layout_marginLeft="50dp"
。因此,将忽略传递给setMarginStart()
的值。