Intereting Posts
Синхронизация проекта Android Studio с файлами Gradle Android: вертикальный ViewPager SparseArray vs HashMap Возвратный переход не работает корректно при использовании общих разделов фрагментов Ловкость OutOfMemoryError в декодировании Растровое изображение Максимальный номер потока для одного приложения? Сообщение «Не удалось найти сообщение XXX.apk» на консоли при запуске приложения с подключенным к ОС Android lib Как настроить ширину и высоту выбора даты в android Функция записи теста Espresso в Android Studio 2.2 Appium: версия сервера adb (31) не соответствует этому клиенту (36) Как преобразовать виды в растровые изображения? Правильный способ преобразования байта в java в unsigned char * в C ++ и наоборот? Ошибка: для Android SDK требуется Android Developer Toolkit версии 22.6.1 или выше Вкладка «Графическая компоновка» не отображается для некоторых файлов макета в Eclipse OnGlobalLayoutListener: устаревание и совместимость

Когда вызывается View.onMeasure ()?

Когда

View.onMeasure(int widthMeasureSpec, int heightMeasureSpec) 

называется? У меня есть Activity, который должен выполнить действие после вызова onMeasure .

Мой вопрос такой же, как и без ответа . В документации « Просмотр» указано, что onMeasure вызывается при вызове функции requestLayout () , которая, по-видимому, называется представлением сама по себе, когда она считает, что она больше не может соответствовать ее текущим границам.

Однако это не говорит мне, когда моя деятельность может предполагать, что мой взгляд был измерен. Я использовал этот код для расширения ImageView для создания TouchImageView. Здесь было предложено использовать метод onMeasure для масштабирования изображения. Я хочу обновить значение TextView после того, как ImageView был измерен, чтобы отобразить процент, по которому масштабируется изображение.

Solutions Collecting From Web of "Когда вызывается View.onMeasure ()?"

OnMeasure вызывается, когда родительский вид должен вычислять макет. Как правило, onMeasure можно вызывать несколько раз в зависимости от разных присутствующих детей и их параметров компоновки.

Лучший способ сделать что-то, когда onMeasure называется (я думаю), создать собственный контроль, расширить ImageView и переопределить onMeasure (просто вызвать super.onMeasure и делать все, что вы хотели бы сделать).

Если вы это сделаете, просто имейте в виду, что на Measure можно вызывать несколько раз с различными параметрами, поэтому все измеренное значение может быть не окончательной шириной и высотой того, что будет отображаться на самом деле.

Вы можете получить измерения пользовательского вида в onSizeChanged .

 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // use the provided width and height for whatever you need } 

объяснение

Когда создается представление, это порядок, в котором вызываются следующие методы:

  1. Конструктор
  2. onFinishInflate (если вы использовали конструктор xml)
  3. onAttachedToWindow
  4. onMeasure
  5. onSizeChanged
  6. onLayout
  7. onDraw

Самое раннее, что вы можете получить измерения вида, находится в onMeasure . Перед этим ширина и высота равны 0 . Тем не менее, единственное, что вы должны делать в onMeasure – это определить размер представления. Этот метод вызывается несколько раз, в то время как представление сообщает родителям, насколько большой он хочет быть, но родитель определяет фактический конечный размер. (См. Этот ответ для того, как используется onMeasure .)

Если вы хотите фактически использовать измеренный размер для чего-либо, самое раннее место для этого – в onSizeChanged . Он вызывается всякий раз, когда создается представление, потому что размер изменяется с 0 на любой размер.

Вы также можете использовать onLayout , хотя, насколько я понимаю, onLayout предназначен для настройки того, как выкладываются дети вашего пользовательского представления. Его также можно вызывать чаще, чем onSizeChanged , например, если вы вызываете requestLayout() когда размер фактически не изменился.

Вы также можете получить доступ к размеру в onDraw с помощью getMeasuredWidth() и getMeasuredHeight() . Однако, если вы используете их для проведения тяжелых вычислений, лучше сделать это заранее. Вообще говоря, постарайтесь сохранить как можно больше из onDraw так как это можно назвать несколько раз. (Он вызывается всякий раз, когда invalidate() .)

Посмотреть на себя

Если вы мне не верите, вы можете увидеть порядок событий, как они вызывают в пользовательском представлении ниже. Вот результат:

 constructor called, measured size: (0, 0) onFinishInflate called, measured size: (0, 0) onAttachedToWindow called, measured size: (0, 0) onMeasure called, measured size: (350, 1859) onMeasure called, measured size: (350, 350) onMeasure called, measured size: (350, 2112) onMeasure called, measured size: (350, 350) onSizeChanged called, measured size: (350, 350) onLayout called, measured size: (350, 350) onDraw called, measured size: (350, 350) 

activity_main.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.viewlifecycle.CustomView android:id="@+id/customView" android:layout_width="100dp" android:layout_height="100dp" android:background="@color/colorAccent"/> </RelativeLayout> 

CustomView.java

 public class CustomView extends View { private void printLogInfo(String methodName) { Log.i("TAG", methodName + " called, measured size: (" + getMeasuredWidth() + ", " + getMeasuredHeight() + ")"); } // constructors public CustomView(Context context) { super(context); printLogInfo("Programmatic constructor"); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); printLogInfo("XML constructor"); } // lifecycle methods @Override protected void onFinishInflate() { super.onFinishInflate(); printLogInfo("onFinishInflate"); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); printLogInfo("onAttachedToWindow"); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); printLogInfo("onMeasure"); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); printLogInfo("onSizeChanged"); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); printLogInfo("onLayout"); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); printLogInfo("onDraw"); } } 

дальнейшее чтение

  • View документации
  • Как Android рисует представления
  • Жизненный цикл Android View
  • View исходный код