这里主要分析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);
}
其中自定义view需要实现ViewTreeObserver.OnGlobalLayoutListener该接口,
重写方法: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;
}
}