在清单中

时间:2018-10-02 20:59:28

标签: android layout right-to-left

请考虑以下片段:

<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行为还是错误?有人可以解释这种行为吗?

1 个答案:

答案 0 :(得分:0)

tl; dr -android:supportsRtl="false"将应用置于“ RTL兼容模式”,这在定义了startMargin的任何情况下都会导致leftMargin被忽略。删除android:layout_marginLeft="50dp"属性可使startMargin生效。


MarginLayoutParams类中,两个不同的字段跟踪“左边”边距和“开始”边距(它们具有非常有创意的名称:leftMarginstartMargin)。类似地,两个不同的字段跟踪“右”边距和“结束”边距。

该类几乎使用“左”和“右”边距完成所有工作;它只是经历了一个将“开始”和“结束”值(基于布局方向)解析为“左”或“右”的过程。这是该方法的源代码:

    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()的值。