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.

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

Не могли бы вы помочь? Спасибо заранее!

Ответ 1

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

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

MeasureSpec.EXACTLY будет использовать значение spec, 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() что делает это:) Интересно, если это ошибка. Возможно, он должен проверять аргумент за то, что он отрицательный, и выбрасывает исключение или что-то в этом роде.