Странное поведение setMarginStart с false в RTF false в манифесте - PullRequest
0 голосов
/ 02 октября 2018

Рассмотрим следующие фрагменты:

<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);

с установленным флагом trueRTL в манифесте Android, приведенный выше код создает текст с полем 0, как и ожидалось.Тем не менее, при false с supportRTL setMarginStart не действует.

Более того, с false SupportsRTL, независимо от того, как вы устанавливаете левое поле (в xml или программно с помощью setMargins), после установки левого поля setMarginStart не действует наэто.

Это предполагаемое поведение Android или ошибка?Может кто-нибудь объяснить это поведение?

1 Ответ

0 голосов
/ 03 октября 2018

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

...