Разница между addOnLayoutChangeListener и onLayout (изменена)?

У меня есть класс

public class FancyView extends View implements View.OnTouchListener { 

Мне нужно получить высоту / ширину представления.

(Это может измениться, например, при вращении устройства. Также, конечно, высота / ширина неизвестна во время инициализации.)

Вы можете сделать это…

Итак, фактически внутри класса FancyView просто переопределяет onLayout(changed)

 @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); int hh = getHeight(); Log.d("~", "Using onLayout(changed), height is known: " +hh); } 

Или вы можете это сделать …

Опять же в классе FancyView используйте addOnLayoutChangeListener

 private void init() { addOnLayoutChangeListener(new OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { Log.d("~", "Using addOnLayoutChangeListener, height is known: " +hh); } }); } 

(Кроме того: я думаю, что init() – лучшее место для этого.)

Оба, похоже, работают хорошо.

Есть ли какая-либо фактическая разница между (A) добавлением слушателя с addOnLayoutChangeListener и поочередно (B) переопределение onLayout(boolean changed ?

Случай использования: внутри класса FancyView я рисую что-то поверх изображения; Поэтому мне нужно знать ширину / высоту, какой размер рисовать.


Сноска. Я заметил, где бы ни обсуждалась проблема «Android, получить ширину / высоту представления», часто предлагается использовать onWindowFocusChanged 9, так как это «проще»). Я действительно не понимаю, почему вы это сделаете, когда доступно onLayout (изменено); Возможно, я что-то упускаю.

Метод addOnLayoutChangeListener является общедоступным, поэтому он позволяет добавить внешнего прослушивателя изменений. OTOH onLayout защищен, поэтому он предназначен только для внутреннего использования.

Для внутреннего использования я понимаю, что оба метода обеспечивают одинаковый результат, но переопределение немного чище.

Проверка исходного кода для View Я вижу, что этот метод с использованием прослушивателей изменений

 public void layout(int l, int t, int r, int b) 

Этот метод вызывается внутри onLayout и меняет слушателей, подтверждающих, что оба метода эквивалентны, так как они запускаются одинаково. Если есть ситуация, когда они не вызываются одновременно, это может быть вызвано ошибкой в ​​реализации управления.

Intereting Posts
Progressbar в верхней части кнопки в вопросе относительной компоновки в Android Studio Android sqlite турецкий язык Как я могу проверить, сколько свободного места на карте SD, установленной на устройстве Android? Android: Диалог действий / Диалог неожиданно исчезает ActivityOptionsCompat не работает в android 2.3 Android: альтернативный макет xml для ландшафтного режима Android SDK не найден. Убедитесь, что он установлен. Если он не находится по умолчанию, установите переменную среды ANDROID_HOME Зачем использовать DialogFragment? Что делать до экспорта приложения на рынок Android и как включить progaurd (последние) Как загрузить базу данных SQLite с устройства Android? Волейбольная сеть для Android Атрибуты высоты ActionBarSherlock в низком sdk Как сделать работу не в полноэкранном режиме? Как реализовать RecyclerView с строками CardView в фрагменте с помощью TabLayout Broadcast Receiver все еще работает после приложения close – Android