У меня есть вопрос о Android Views, который, кажется, был задан несколько раз. Но я все равно не получаю именно тот ответ, который мне нужен. Мне нужно создать представление, которое изменяет его размер (высоту) в соответствии с заданным процентом. Это означает, что я хочу что-то вроде
setHeight(percentage){ view.setHeight(Originl * percentage) }
Для этого мне нужна оригинальная высота представления без каких-либо изменений или внешнего макета (поэтому нет Match_Parent). Есть много способов и возможных моментов для вычисления высоты просмотров, но все они, похоже, имеют текущую высоту, а не «желаемую».
Например, я пытался использовать onMeasure (), так как это момент, когда вид измеряется, но он также вызывается при изменении взглядов. Это также делается на вид «создание» несколько раз. Поэтому я не могу даже взять первое значение, которое приходит, потому что его иногда вызывают дважды, когда первое измерение дает неправильные данные (например, высота 0, пока вторая onMeasure не даст реальную).
Я теперь сделал то, что тоже не очень здорово, но, похоже, работает. Я добавил слушателя так
getViewTreeObserver().addOnGlobalLayoutListener( this)
и в методе обратного вызова я удаляю слушателя
override fun onGlobalLayout() { Log.d("OnGlobalLayout", "Height: $height") originalHeight = height getViewTreeObserver().removeOnGlobalLayoutListener( this) }
Кажется, это работает более или менее, но действительно ли это способ? Я надеялся на какой-то метод, который получает ожидаемый размер вида независимо от того, каков текущий.
Любые идеи, как это сделать?
Вы можете написать расширение один раз для таких просмотров
inline fun View.afterMeasured(crossinline f: View.() -> Unit) { viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { if (measuredHeight > 0 && measuredWidth > 0) { viewTreeObserver.removeOnGlobalLayoutListener(this) f() } } }) }
Чем просто написать
mView.afterMeasured { // inside this block the view is completely drawn, // here you have an access for its height and width }