在运行时确定一个Android视图的大小

我正在尝试在我的活动创build后,将animation应用到我的Android应用中的视图。 为此,我需要确定视图的当前大小,然后设置一个animation以从当前大小缩放到新大小。 这部分必须在运行时完成,因为视图根据用户的input缩放到不同的大小。 我的布局是用XML定义的。

这似乎是一件容易的事情,显然,没有任何解决我的问题的问题有很多。 所以也许我错过了一些明显的东西。 我通过以下方式了解我的观点:

ImageView myView = (ImageView)getWindow().findViewById(R.id.MyViewID); 

这工作正常,但是当调用getWidth()getHeight()getMeasuredWidth()getLayoutParams().width等,他们都返回0.我也尝试手动调用measure()视图,然后调用getMeasuredWidth() ,但是没有效果。

我已经尝试调用这些方法,并在我的activity的onCreate()onPostCreate()检查debugging器中的对象。 如何在运行时找出这个视图的确切尺寸?

使用视图上的ViewTreeObserver等待第一个布局。 只有在第一个布局将getWidth()/ getHeight()/ getMeasuredWidth()/ getMeasuredHeight()工作。

 ViewTreeObserver viewTreeObserver = view.getViewTreeObserver(); if (viewTreeObserver.isAlive()) { viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { view.getViewTreeObserver().removeOnGlobalLayoutListener(this); viewWidth = view.getWidth(); viewHeight = view.getHeight(); } }); } 

实际上有多种解决scheme,具体情况取决于:

  1. 安全的方法,将在绘制视图之前工作,在布局阶段结束之后:
 public static void runJustBeforeBeingDrawn(final View view, final Runnable runnable) { final OnPreDrawListener preDrawListener = new OnPreDrawListener() { @Override public boolean onPreDraw() { view.getViewTreeObserver().removeOnPreDrawListener(this); runnable.run(); return true; } }; view.getViewTreeObserver().addOnPreDrawListener(preDrawListener); } 
  1. 在某些情况下,手动测量视图的大小就足够了:
 view.measure(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); int width=view.getMeasuredWidth(); int height=view.getMeasuredHeight(); 
  1. 如果您已经扩展了自定义视图,则可以在“onMeasure”方法上获得它的大小,但是我认为它只适用于某些情况:
 protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { final int newHeight= MeasureSpec.getSize(heightMeasureSpec); final int newWidth= MeasureSpec.getSize(widthMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } 

在视图实际布置在屏幕上之前,你是否调用getWidth()

新的Android开发者犯的常见错误是在构造函数中使用视图的宽度和高度。 当视图的构造函数被调用时,Android不知道视图有多大,所以尺寸被设置为零。 实际尺寸是在布置阶段计算的,这个阶段是在施工之后,在任何事情出现之前进行的。 您可以使用onSizeChanged()方法在知道这些值时通知这些值,也可以稍后使用getWidth()getHeight()方法,例如在onDraw()方法中。

基于@ mbaird的build议,我通过onLayout() ImageView类并重写onLayout() ,find了一个可行的解决scheme。 然后我创build了一个观察者接口,这个接口让我的活动实现,并将一个对自身的引用传递给这个类,这个接口允许它在实际完成大小调整时告诉活动。

我并不是100%相信这是最好的解决scheme(因此我没有把这个答案标记为正确),但它确实有效,根据文档是第一次可以find视图的实际大小。

如果API <11(API 11包含View.OnLayoutChangedListenerfunction),则通过覆盖视图获取布局的代码如下:

 public class CustomListView extends ListView { private OnLayoutChangedListener layoutChangedListener; public CustomListView(Context context) { super(context); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (layoutChangedListener != null) { layoutChangedListener.onLayout(changed, l, t, r, b); } super.onLayout(changed, l, t, r, b); } public void setLayoutChangedListener( OnLayoutChangedListener layoutChangedListener) { this.layoutChangedListener = layoutChangedListener; } } public interface OnLayoutChangedListener { void onLayout(boolean changed, int l, int t, int r, int b); } 

你可以检查这个问题 。 你可以使用View的post()方法。

这在我的onClickListener适用于我:

 yourView.postDelayed(new Runnable() { @Override public void run() { yourView.invalidate(); System.out.println("Height yourView: " + yourView.getHeight()); System.out.println("Width yourView: " + yourView.getWidth()); } }, 1); 

我也失去了很长一段时间getMeasuredWidth()getMeasuredHeight() getHeight()getWidth() ……….后来我发现在onSizeChanged()获取视图的宽度和高度是最好的这样做的方法……..你可以通过重写onSizeChanged( )方法dynamic获取你的视图的CURRENT宽度和CURRENT高度。

可能想看看这个有详细的代码片断。 新的博客文章:如何获取自定义视图的宽度和高度尺寸(扩展视图)在Android http://syedrakibalhasan.blogspot.com/2011/02/how-to-get-width-and-height-dimensions.html

使用下面的代码,它是给视图的大小。

 @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); Log.e("WIDTH",""+view.getWidth()); Log.e("HEIGHT",""+view.getHeight()); } 

对我来说完美的作品:

  protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); CTEditor ctEdit = Element as CTEditor; if (ctEdit == null) return; if (e.PropertyName == "Text") { double xHeight = Element.Height; double aHaight = Control.Height; double height; Control.Measure(LayoutParams.MatchParent,LayoutParams.WrapContent); height = Control.MeasuredHeight; height = xHeight / aHaight * height; if (Element.HeightRequest != height) Element.HeightRequest = height; } }