Android:在视图之前获取视图的高度´;画

Android:在视图之前获取视图的高度´;画,android,layout,view,height,Android,Layout,View,Height,对于动画,我需要从视图中了解高度。问题是,除非绘制视图,否则getHeight()方法总是返回0。 那么,有没有办法不用画就可以得到高度呢 在这种情况下,视图是线性布局 编辑: 我尝试从中调整扩展动画 有了它,我想为一个列表项扩展更多的信息。 我无法通过xml实现同样的效果。 目前,动画仅在绘制之前知道布局大小时才起作用。从技术上讲,您可以在视图上调用measure方法,然后通过getMeasureHeight获取其高度。有关详细信息,请参见此:。不过,您需要给它一个MeasureSpec 但实

对于动画,我需要从视图中了解高度。问题是,除非绘制视图,否则getHeight()方法总是返回0。 那么,有没有办法不用画就可以得到高度呢

在这种情况下,视图是线性布局

编辑: 我尝试从中调整扩展动画

有了它,我想为一个列表项扩展更多的信息。 我无法通过xml实现同样的效果。
目前,动画仅在绘制之前知道布局大小时才起作用。

从技术上讲,您可以在视图上调用
measure
方法,然后通过
getMeasureHeight
获取其高度。有关详细信息,请参见此:。不过,您需要给它一个
MeasureSpec

但实际上,视图的大小受其父布局的影响,因此您可能会得到与实际绘制时不同的大小


此外,您可以尝试在动画中使用相对值。

您可以尝试从视图可见开始,然后添加如下内容:

view.post(new Runnable() {      
    @Override
    public void run() {
        // hide view here so that its height has been already computed
        view.setVisibility(View.GONE);
    }
});
现在,当您调用view.getHeight()时,它应该返回您期望的高度


我不确定这是否真的是一个好方法,但至少它应该能起作用。

好的,关于更新后的帖子,以下是对你有帮助的:
方法。你应该把初始化放在那里,而不是构造函数,这样你就有了你需要的所有尺寸。

听起来你想得到高度,但在视图可见之前隐藏它

首先将视图中的可见性设置为可见或不可见(以便创建高度)。不用担心,我们会在代码中将其更改为“不可见/消失”,如下所示:

private int mHeight = 0;
private View mView;

class...

// onCreate or onResume or onStart ...
mView = findViewByID(R.id.someID);
mView.getViewTreeObserver().addOnGlobalLayoutListener( 
    new OnGlobalLayoutListener(){

        @Override
        public void onGlobalLayout() {
            // gets called after layout has been done but before display
            // so we can get the height then hide the view


            mHeight = mView.getHeight();  // Ahaha!  Gotcha

            mView.getViewTreeObserver().removeGlobalOnLayoutListener( this );
            mView.setVisibility( View.GONE );
        }

});

我有一个类似的问题和类似的情况

我必须创建一个动画,我需要该动画的
视图的高度。在
视图
中,这是一个
线性布局
可以是
文本视图
类型的子视图。
TextView
是多行的,实际需要的行数不同

无论我做了什么,我只是得到了视图的测量高度,就好像
TextView
只有一行要填充一样。难怪每次文本短到可以容纳一行时,这种方法都能很好地工作,但当文本比行长时,这种方法就失败了

我考虑过这个答案: 但是这个对我来说效果不太好,因为我无法直接从这里访问嵌入的
TextView
。(不过,我本可以遍历子视图树。)

请查看我的代码,因为它目前正在运行:

视图
是要设置动画的视图。这是一个
线性布局
(最终的解决方案将是更多的类型保存在这里)
是一个自定义视图,它包含
视图
,并继承自
线性布局

   private void expandView( final View view ) {

      view.setVisibility(View.VISIBLE);

      LayoutParams parms = (LayoutParams) view.getLayoutParams();
      final int width = this.getWidth() - parms.leftMargin - parms.rightMargin;

      view.measure( MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
              MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

      final int targetHeight = view.getMeasuredHeight();

      view.getLayoutParams().height = 0;

      Animation anim = new Animation() {
         @Override
         protected void applyTransformation( float interpolatedTime, Transformation trans ) {
            view.getLayoutParams().height =  (int) (targetHeight * interpolatedTime);
            view.requestLayout();
         }

         @Override
         public boolean willChangeBounds() {
            return true;
         }
      };

      anim.setDuration( ANIMATION_DURATION );
      view.startAnimation( anim );
   }
差一点,但我又犯了一个错误。在视图层次结构中,涉及到两个自定义视图,它们是
LinearLayout
的子类,它们的xml与
merge
标记合并为xml根标记。在其中一个
merge
标记中,我忽略了将
android:orientation
属性设置为
vertical
。 这对布局本身来说并没有太大的麻烦,因为在这个合并的
视图组中只有一个子
视图组
,因此我实际上看不到屏幕上的错误方向。但它就在那里,有点打破了这种布局测量逻辑


除上述内容外,可能还需要去除与视图层次结构中的
LinearLayout
s和子类相关的所有填充。将它们替换为边距,即使您必须围绕另一个布局使其看起来相同

如果父对象不确定其大小,请自己测量:

static void getMeasurments(View v) {

    v.measure(View.MeasureSpec.makeMeasureSpec(PARENT_VIEW.getWidth(), 
      View.MeasureSpec.EXACTLY),
         View.MeasureSpec.makeMeasureSpec(0, 
      View.MeasureSpec.UNSPECIFIED));

    final int targetHeight = v.getMeasuredHeight();
    final int targetWidth = v.getMesauredWidth();
}
以下是视图上的kotlin扩展,可随时为您执行此操作:

fun View.getMeasurments(): Pair<Int, Int> {
    measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
    val width = measuredWidth
    val height = measuredHeight
    return width to height
}
fun View.getmeasurements():对{
度量值(View.MeasureSpec.unspected,View.MeasureSpec.unspected)
val宽度=测量宽度
val高度=测量高度
返回宽度到高度
}
虽然一开始似乎是可行的,但最终我注意到它弄乱了正在测量的视图。 我通过传递父视图修复了它

/**
 * class to map width and height values.
 */
data class Point(val width: Int, val height: Int)

/**
 * Measures the view and returns the width and height.
 */
fun View.getMeasurements(parent: View): Point {
    measure(View.MeasureSpec.makeMeasureSpec(parent.width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(parent.height, View.MeasureSpec.UNSPECIFIED))

    return Point(measuredWidth, measuredHeight)
}
我还创建了一个数据类,使其更易于读取值所表示的内容。 现在可以像这样访问结果值

child.getMeasurements(parent).width
还是这个

child.getMeasurements(parent).height

事实上,getMeasuredSpec返回的高度是不同的。目前34对137。我用更多的信息编辑了我的第一条消息。这个答案是正确的,但缺少代码是投票次数减少的简单原因。请确保在之后调用
getmeasuredheath()
,而不是
getHeight()
!我忽略了这一点,花了一段时间认为这不起作用。另外,如果您不关心剪裁,可以调用
measure(0,0)
。很好,嗯。。。我不明白。除非视图可见且未消失,否则高度也为0。请尝试使用
不可见
而不是
消失
。这可能是一个很好的提示。但是现在动画并不是马上就开始。有时,如果我滚动或以某种方式与ui交互,会首先出现。如何将动画分配给视图?用什么方法?用什么方法?用布局。开始动画(动画);但是我可以通过调用layout.requestLayout()来解决这个问题;现在唯一的问题是,我必须为要扩展的shell设置android:layout_marginBottom=“-9999dip”,否则我无法将其设置为不可见而不是消失。谢谢,它可以工作!只需添加一点:RemoveGlobalOnlyOutliner()自从API级别16以来就被弃用了,它被removeOnGlobalLayoutListener()所取代。谢谢您对我的帮助。视图的测量有问题。谢谢你的提示,它工作得很好。请注意,事实上,该参数的名称