Измерение представления перед его рендерингом
Мне нужно выяснить, насколько большой будет просмотр после присоединения его к его родительскому объекту.
Я переопределил этот метод:
onMeasure(int, int);
но похоже, что этот метод вызывается только тогда, когда я фактически добавляю свой пользовательский вид в контейнер, используя:
addView(myView);
Считаете ли вы, что есть способ получить эту информацию, прежде чем сделать это? В принципе, мне нужно знать размер исполнительного механизма, прежде чем присоединять его, а не прикреплять вид вообще, если потребуется более определенное пространство.
кто-нибудь?
Ответы
Ответ 1
Если вы хотите получить ширину и высоту до того, как ваша активность добавила ее в свою иерархию представлений, ее измерили и выложили, вы должны будете вызвать measure()
на View
самостоятельно, прежде чем называть getMeasuredWidth()
или getMeasuredHeight()
.
Поскольку измеренная ширина и высота задаются после вызова меры (которая, в свою очередь, вызывает onMeasure()
), они возвращают 0 до этой точки. Вам нужно будет поставить MeasureSpec
на measure(..)
, который будет зависеть от ваших потребностей.
Параметры MeasureSpec, которые позволяют детям самим навязывать какие-либо ограничения, выглядят как
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(*some width*, MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(*some height*, MeasureSpec.EXACTLY);
Важная точка. (был изменен в новом API) Ширина, указанная выше, может быть либо явной px, либо ViewGroup.LayoutParams.WRAP_CONTENT
или ViewGroup.LayoutParams.FILL_PARENT.
Также стоит отметить, что когда ваше представление измеряется в фактической целевой иерархии, MeasureSpec, который будет передан в measure()
, будет настроен на основе содержащейся логики компоновки ViewGroups
. Он может быть вызван более одного раза, если первые меры vals недействительны при рассмотрении в контексте этого родительского представленияGroup/его собственных ограничений компоновки/ограничений любого дочернего представления sibling. Не дожидаясь, пока viewGroup
вызовет measure()
, прежде чем реализовать какую-либо логику, зависящую от измеренного размера, было бы сложно (в зависимости от ситуации) получить окончательный measuredWidth & height
из вышеупомянутого решения, но во всех случаях я использовал вышеупомянутый метод, который соответствует цели, но они были относительно просты. Если вам действительно нужно измерять в контексте, вы, вероятно, должны просто сделать это после того, как onLayout()
вернется и явно изменит любые изменения, затем requestLayout()
снова.
Ответ 2
OnMeasure не сообщает вам размер представления. Вместо этого он запрашивает, чтобы ваш пользовательский вид устанавливал свой размер, предоставляя некоторые ограничения, выполняемые родительским представлением.
Это из документации SDK:
Первая пара известна как измеренная ширины и измеренной высоты. Эти размеры определяют, насколько большой вид нужен быть в пределах своего родителя (см. Макет для более подробной информации.) Измеренный размеры могут быть получены путем вызова getMeasuredWidth() и getMeasuredHeight().
Вторая пара просто известна как ширины и высоты, а иногда и рисования ширины и высоты рисунка. Эти размеры определяют фактический размер вид на экране, во время рисования и после макета. Эти значения могут, но не нужно, отличаться от измеренная ширина и высота. ширины и высоты можно получить вызов getWidth() и getHeight().
После макета вы можете вызвать getWidth() и getHeight(), чтобы найти конечный размер вашего пользовательского представления.
Ответ 3
Вы должны иметь возможность использовать getMesauredWith() и getMeasuredHeight()
http://developer.android.com/reference/android/view/View.html#getMeasuredWidth%28%29
Ответ 4
У меня такая же проблема. Я предполагаю, что единственный способ - сделать его первым, а затем удалить его, если он соответствует условию размера. Кажется немного странным, но Android, похоже, знает размеры после рисования.
Ответ 5
первый звонок
view.measure(0, 0);
тогда получите
view.getMeasuredWidth()
или view.getMeasuredHeight()
Ответ 6
Я уже ответил на очень похожий вопрос раньше.
Вот все способы сделать это: fooobar.com/info/35172/...