Передать значения ширины и высоты объекта перед показом Activity в переменные
На экране у меня FrameLayout и LinerLayout. Во FrameLayout я хочу разместить в определенном месте какой-либо объект. Например, картинку. Ее расположение зависит от размера контейнера. Для размещения картинки мне необходимо вычислить ширину и высоту FrameLayout. Если я пытаюсь узнать ширину и высоту FrameLayout в методе onCreate(), то получаю значения 0. Ведь у нас экран еще не нарисовался.
Если я пытаюсь узнать ширину и высоту FrameLayout используя метод onResume(), то тоже получаю 0. Здесь я не совсем понял, почему возвращаются 0.
На данном ресурсе я нашел код, который получает ширину и высоту нужного мне объекта, но возникла проблема, как передать эти значения в другие переменные, чтобы использовать их там, где мне необходимо.
Я создал глобальные переменные, и в них передаю значения ширины и высоты, но как только метод заканчивает работу, значения опять обнуляются. Мой код
// Объявил ДО класса MainActivity
var elementHeight = 0
var elementWidth = 0
// Эти методы уже в классе MainActivity
override fun onResume() {
super.onResume()
countWidthHeight()
}
fun countWidthHeight() {
val flayerLayout = binding.container
flayerLayout.getViewTreeObserver()
.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
flayerLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this)
// Здесь ширина и высота вычисляются правильно
elementHeight = flayerLayout.height //height is ready
elementWidth = flayerLayout.width
}
})
}
fun viewHeightWidth() {
// а здесь oneHeight и oneWidth уже равны 0 хотя им передаются значения глобальных переменных
val oneHeight = elementHeight
val oneWidth = elementWidth
}
Подскажите, что я делаю неправильно. Kotlin и Android начал изучать не так давно.
Ответы (2 шт):
Запустив Вашу программу, убедился в своих мыслях.
Как я выяснил в комментариях, viewHeightWidth() запускается из метода onResume().
override fun onResume() {
super.onResume()
countWidthHeight()
viewHeightWidth()
}
- Мы вызвали функцию
countWidthHeight(), добавилиViewTreeObserver.OnGlobalLayoutListener(Ещё раз повторю, мы ТОЛЬКО добавили его, т.е. в данный момент сам листенер ещё не вызывался) - Дальше по порядку идет вызов функции
viewHeightWidth(), которая использует глобальные переменные, которые не успели поменяться, т.е равны 0.
2 Способа решить вашу проблему
Первый способ:
Сделать вызов viewHeightWidth(), внутри ViewTreeObserver.OnGlobalLayoutListener.
fun countWidthHeight() {
val flayerLayout = binding.container
flayerLayout.getViewTreeObserver()
.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
flayerLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this)
elementHeight = flayerLayout.height
elementWidth = flayerLayout.width
viewHeightWidth()
}
})
}
Второй способ: Избавьтесь от OnGlobalLayoutListener и используйте View.post (документация)
override fun onResume() {
super.onResume()
binding.container.post {
viewHeightWidth()
}
}
fun viewHeightWidth() {
val oneHeight = binding.container.height
val oneWidth = binding.container.width
}
Для подобных задач хорошо подходит слушатель View.OnLayoutChangeListener : просто добавьте его к ViewGroupв методе onCreate активности.
ViewGroup veiw_group = findViewById( R.id.root );
veiw_group.addOnLayoutChangeListener( new View.OnLayoutChangeListener(){
@Override
public void onLayoutChange( View view, int left, int top, int right, int bottom, int i4, int i5, int i6, int i7 ){
}
} );