这里主要分析View的两个重要方法:
方法一:protected void onAttachedToWindow ()
当view附加到窗口的时候被调用,这个时候有一个面板提供绘画,
这个方法要确保在方法onDraw(android.graphics.Canvas)之前被调用,
但是这个方法可能在第一次调用onDraw()方法之前的任何时间被调用,
包括在调用方法onMeasure(int,int)前或者后面。
在Activity中的生命周期为:onCreate->onStart->onResume->onAttachedToWindow
onAttachedToWindow只会调用一次,不会受用户操作行为影响。
具体的Android应用程序窗口(Activity)的视图对象(View)的创建过程请参考Android应用程序窗口(Activity)的视图对象(View)的创建过程
我们知道在onCreate中View.getWidth和View.getHeight无法获得一个view的高度和宽度,这是因为View组件布局要在onResume回调后完成。所以现在需要使用
getViewTreeObserver().addOnGlobalLayoutListener()来获得宽度或者高度。这是获得一个view的宽度和高度的方法之一。
具体使用如下:
@Override protected void onAttachedToWindow() { Log.d("ZHR","onAttachedToWindow()"); super.onAttachedToWindow(); getViewTreeObserver().addOnGlobalLayoutListener(this); }
重写方法:onGlobalLayout(),该方法中可以获取到自定义view的宽度和高度。
<pre name="code" class="java">@Override public void onGlobalLayout() { Log.d("ZHR","onGloballLayout()"); Drawable d = getDrawable(); if (d == null) return; //获取屏幕的宽和高 int width = getWidth(); int height = getHeight(); // 获取图片的宽和高 int dw = d.getIntrinsicWidth(); int dh = d.getIntrinsicHeight(); }
方法二:protected void onDetachedFromWindow ()
当view脱离窗口的时候被调用,这个时候不再有提供绘画的面板。
具体例子如下:
public class MyImageView extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener { private final Matrix mScaleMatrix = new Matrix(); private boolean isFirst = true; private float initScale = 1.0f; public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnGlobalLayoutListener(this); } @SuppressWarnings("deprecation") @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); getViewTreeObserver().removeGlobalOnLayoutListener(this); } @Override public void onGlobalLayout() { if (isFirst) { Drawable drawable = getDrawable(); if (drawable == null) { return; } //获取屏幕的宽和高 int width = getWidth(); int height = getHeight(); //获取图片的宽和高 int viewWidth = drawable.getIntrinsicWidth(); int viewHeight = drawable.getIntrinsicHeight(); float scale = 1.0f; //如果图片的宽大于屏幕的宽而且控件的高小于屏幕的高 if (viewWidth > width && viewHeight <= height) { scale = width * 1.0f / viewWidth; } //如果控件的高大于屏幕的高而且控件的宽小于屏幕的宽 if (viewHeight > height && viewWidth <= width) { scale = height * 1.0f / viewHeight; } // 如果宽和高都大于屏幕,则让其按比例适应屏幕大小 if (viewWidth > width && viewHeight > height) { scale = Math.min(width * 1.0f / viewWidth, height * 1.0f / viewHeight); } initScale = scale; // 图片移动至屏幕中心 mScaleMatrix.postTranslate((width - viewWidth) / 2, (height - viewHeight) / 2); //以屏幕中心为中点进行缩放 mScaleMatrix.postScale(scale, scale, width / 2, height / 2); setImageMatrix(mScaleMatrix); isFirst = false; } }