getMeasuredWidth возвращает совершенно неверное значение

Я должен измерить View для разнесения других. Я использую этот код для этого:

ViewGroup view = ...;
view.setPadding(10, 0, 10, 0);
int wrapContent = RelativeLayout.LayoutParams.WRAP_CONTENT;
int specWidth = MeasureSpec.makeMeasureSpec(wrapContent, MeasureSpec.AT_MOST);
view.measure(specWidth, specWidth);
int questionWidth = view.getMeasuredWidth();

Это работает, как и ожидалось, на эмуляторе Android 4.3.

Однако возвращенная измеренная ширина на телефоне Android 4.1.2 Samsung Galaxy XCover 2 (S7710) составляет 16777214... Я все перепробовал, маскируя с View.MEASURED_SIZE_MASK, но ничего не помогло.

Не могли бы вы помочь с этим? Заранее спасибо!

1 ответ

Решение

Переходя WRAP_CONTENT вместо фактического значения makeMeasureSpec() не принесет пользы, я не думаю, что они должны были использоваться вместе.

Использовать фактическое значение ограничения в качестве первого параметра (например, размер родительского представления или размеры экрана) с MeasureSpec.AT_MOST режим, который в основном Math.min() - аргументами являются значение, которое вы указали в спецификации, и желаемое измерение представления.

MeasureSpec.EXACTLY заставит его использовать значение спецификации, MeasureSpec.UNSPECIFIED заставит это использовать желаемое значение представления. Так что, если у вас нет каких-либо ограничений (например, если вы поместите свой взгляд в ScrollView) ваш вариант MeasureSpec.UNSPECIFIED - и любое значение в качестве первого аргумента.

Итак, {гуру, поправьте меня, если я ошибаюсь} вы получите WRAP_CONTENT поведение в любом режиме, кроме MeasureSpec.EXACTLY

Как говорится, попробуйте:

ViewGroup view = ...;
view.setPadding(10, 0, 10, 0);
// Either this
int specWidth = MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.AT_MOST);
// Or this
int specWidth = MeasureSpec.makeMeasureSpec(0 /* any */, MeasureSpec.UNSPECIFIED);
view.measure(specWidth, specWidth);
int questionWidth = view.getMeasuredWidth();

PS Забавная вещь о 16777214, взгляните на число в двоичном виде: https://www.google.ru/search?q=16777214+in+binary Это -2 (что является постоянным значением LayoutParams.WRAP_CONTENT) но с 8 наиболее значимыми битами, усеченными с помощью логической операции (следовательно, без минуса), в стеке вызовов есть что-то measure() это делает это:) Интересно, если это ошибка. Может быть, стоит проверить аргумент на отрицательность и выдать исключение или что-то в этом роде.

Другие вопросы по тегам