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()
, игнорируется.