Android View получает оригинал «Wrap Content» Размер моего представления

У меня есть вопрос о 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 }