В чем разница между getWidth / Height () и getMeasuredWidth / Height () в Android SDK?

88

В документации Android говорится, что существует два размера вида: измеренные размеры и размеры чертежа . Измеряемый размер - это размер, вычисленный на этапе измерения ( метод onMeasure ), а размеры чертежа - это фактический размер на экране. В частности, в документации сказано, что:

Эти значения могут, но не обязательно, отличаться от измеренных ширины и высоты.

Итак, мой вопрос: что может сделать размер чертежа отличным от измеренного? Если метод onMeasure (int, int) соблюдает требования к макету (заданные параметрами widthMeasureSpec и heightMeasureSpec , как SDK может решить , что представление должно иметь другой размер рисунка?)

Кроме того, как / где в исходном коде Android измеренная ширина / высота используется для вычисления ширины / высоты чертежа? Я попытался заглянуть в исходный код View , но не могу понять, как измеренная ширина / высота используется для вычисления окончательной ширины / высоты. Возможно, это как-то связано с обивкой, но я не уверен.

lgfischer
источник
Я думаю, что эти меры могут быть разными, если в представление добавлен свиток.
Юрий
Возможно, но я разработал собственную ViewGroup, и это происходит в моем коде. Я не занимаюсь прокруткой до момента, когда это происходит. Так что я думаю, что здесь должно быть что-то большее, чем просто прокрутка.
lgfischer
Подтверждаю, я также разрабатываю пользовательскую группу ViewGroup, чтобы заставить заданное соотношение сторон: я принудительно измерял ширину и высоту (ниже или равные предложенным), но в результате у меня не изменились реальные ширина и высота (а не измеренные). Никакого отношения к свитку. Я действительно не могу найти способ заставить реальную ширину и высоту.
ARLabs

Ответы:

96

Как следует из названия, измеренная ширина / высота используется на этапе измерения и компоновки.

Приведу пример,

Виджету предлагается измерить себя. Виджет сообщает, что он хочет быть размером 200 на 200 пикселей. Это измеренная ширина / высота.

На этапе макета, то есть в методе onLayout. Метод может использовать измеренную ширину / высоту своих дочерних элементов или назначить новую ширину / высоту, вызвав метод макета представления.

Допустим, метод onLayout вызывает childview.layout (0,0,150,150), теперь ширина / высота представления отличается от измеренной ширины / высоты.

Я бы посоветовал не использовать измеренную ширину / высоту вне метода onLayout.

обобщить .

  1. onMeasure -> устанавливает измеренную ширину / измеренную высоту
  2. onLayout -> устанавливает ширину / высоту виджета.

Кроме того,
public void View.layout(int l, int t, int r, int b)
кажется, что это место, где происходит присвоение позиции и размера.

Пракаш Надар
источник
то есть мы всегда должны использовать getWidth / getHeight, чтобы получить «реальное» измерение представления, верно?
суитянши
1
Да, но если вы делаете собственное макетирование, вам следует использовать измеренную ширину вместо ширины.
Prakash Nadar
Итак, какова цель установки размеров внутри onMeasure ()? Я имею в виду, проход макета - последний, в котором вы устанавливаете окончательные размеры вида, возможно, независимо от измеренных размеров
edoardotognoni
@edoardotognoni зависит от макета (LinearLayout, RelativeLayout или вашего настраиваемого макета), чтобы дать правильный размер и положение для представления.
Prakash Nadar
Хорошо, допустим, вид говорит: «Мне нужны эти размеры». Хотя в макете написано «У вас будут такие размеры». Это правильно?
edoardotognoni