1. 自定义View常用方法执行顺序
1.创建MyView继承View
public class MyView extends View {
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
Log.d("MyView", "MyView(2): ");
}
@Override
protected void onFinishInflate() {
Log.d("MyView", "onFinishInflate: ");
super.onFinishInflate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d("MyView", "onMeasure: ");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
Log.d("MyView", "onDraw: ");
super.onDraw(canvas);
}
@Override
protected void dispatchDraw(Canvas canvas) {
Log.d("MyView", "dispatchDraw: ");
super.dispatchDraw(canvas);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Log.d("MyView", "onLayout: ");
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d("MyView", "onSizeChanged: ");
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onAttachedToWindow() {
Log.d("MyView", "onAttachedToWindow: ");
super.onAttachedToWindow();
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
Log.d("MyView", "onWindowFocusChanged: ");
super.onWindowFocusChanged(hasWindowFocus);
}
}
2.xml文件中使用
<com.wgheng.test.MyView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp">
</com.wgheng.test.MyViewGroup>
3.Log输出情况
06-30 08:19:44.487 11310-11310/com.wgheng.text D/MyView: MyView(2):
06-30 08:19:44.487 11310-11310/com.wgheng.text D/MyView: onFinishInflate:
06-30 08:19:44.540 11310-11310/com.wgheng.text D/MyView: onAttachedToWindow:
06-30 08:19:44.553 11310-11310/com.wgheng.text D/MyView: onMeasure:
06-30 08:19:44.673 11310-11310/com.wgheng.text D/MyView: onMeasure:
06-30 08:19:44.673 11310-11310/com.wgheng.text D/MyView: onSizeChanged:
06-30 08:19:44.673 11310-11310/com.wgheng.text D/MyView: onLayout:
06-30 08:19:44.704 11310-11310/com.wgheng.text D/MyView: onWindowFocusChanged:
06-30 08:19:44.706 11310-11310/com.wgheng.text D/MyView: onMeasure:
06-30 08:19:44.706 11310-11310/com.wgheng.text D/MyView: onLayout:
06-30 08:19:44.707 11310-11310/com.wgheng.text D/MyView: onDraw:
06-30 08:19:44.707 11310-11310/com.wgheng.text D/MyView: dispatchDraw:
从日志中可以看到onWindowFocusChanged()执行时View已经完成了初步的Layout。
Activity生命周期执行的过程中获得或失去焦点时会回调同名的方法,在此同名方法中又回调了View的onWindowFocusChanged()方法,因此比较适合在Activity的onWindowFocusChanged()方法中获取视图的宽和高。
如果在Activity其他方法中获取View的宽和高,很有可能View还未初始化完毕,获得的值为0。
2. 自定义ViewGroup常用方法执行顺序
1.自定义MyViewGroup继承ViewGroup(简单起见继承LinearLayout测试)
public class MyViewGroup extends LinearLayout {
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
Log.d("MyViewGroup", "MyViewGroup(2): ");
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d("MyViewGroup", "onMeasure: ");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.d("MyViewGroup", "onLayout: ");
super.onLayout(changed, l, t, r, b);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d("MyViewGroup", "onSizeChanged: ");
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
Log.d("MyViewGroup", "onDraw: ");
super.onDraw(canvas);
}
@Override
protected void dispatchDraw(Canvas canvas) {
Log.d("MyViewGroup", "dispatchDraw: ");
super.dispatchDraw(canvas);
}
@Override
protected void onFinishInflate() {
Log.d("MyViewGroup", "onFinishInflate: ");
super.onFinishInflate();
}
@Override
protected void onAttachedToWindow() {
Log.d("MyViewGroup", "onAttachedToWindow: ");
super.onAttachedToWindow();
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
Log.d("MyViewGroup", "onWindowFocusChanged: ");
super.onWindowFocusChanged(hasWindowFocus);
}
}
2.xml文件中使用
1> 未设置背景
<com.wgheng.test.MyViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp">
</com.wgheng.test.MyViewGroup>
1> 设置背景
<com.wgheng.test.MyViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#000000">
</com.wgheng.test.MyViewGroup>
3.Log输出情况
1> 未设置背景输出情况
06-30 08:20:52.594 12349-12349/com.wgheng.text D/MyViewGroup: MyViewGroup(2):
06-30 08:20:52.594 12349-12349/com.wgheng.text D/MyViewGroup: onFinishInflate:
06-30 08:20:52.639 12349-12349/com.wgheng.text D/MyViewGroup: onAttachedToWindow:
06-30 08:20:52.644 12349-12349/com.wgheng.text D/MyViewGroup: onMeasure:
06-30 08:20:52.736 12349-12349/com.wgheng.text D/MyViewGroup: onMeasure:
06-30 08:20:52.736 12349-12349/com.wgheng.text D/MyViewGroup: onSizeChanged:
06-30 08:20:52.738 12349-12349/com.wgheng.text D/MyViewGroup: onLayout:
06-30 08:20:52.763 12349-12349/com.wgheng.text D/MyViewGroup: onWindowFocusChanged:
06-30 08:20:52.765 12349-12349/com.wgheng.text D/MyViewGroup: onMeasure:
06-30 08:20:52.765 12349-12349/com.wgheng.text D/MyViewGroup: onLayout:
06-30 08:20:52.766 12349-12349/com.wgheng.text D/MyViewGroup: dispatchDraw:
2> 设置背景输出情况
06-30 08:30:51.470 21347-21347/com.wgheng.test D/MyViewGroup: MyViewGroup(2):
06-30 08:30:51.470 21347-21347/com.wgheng.test D/MyViewGroup: onFinishInflate:
06-30 08:30:51.541 21347-21347/com.wgheng.test D/MyViewGroup: onAttachedToWindow:
06-30 08:30:51.557 21347-21347/com.wgheng.test D/MyViewGroup: onMeasure:
06-30 08:30:51.675 21347-21347/com.wgheng.test D/MyViewGroup: onMeasure:
06-30 08:30:51.675 21347-21347/com.wgheng.test D/MyViewGroup: onSizeChanged:
06-30 08:30:51.675 21347-21347/com.wgheng.test D/MyViewGroup: onLayout:
06-30 08:30:51.776 21347-21347/com.wgheng.test D/MyViewGroup: onWindowFocusChanged:
06-30 08:30:51.779 21347-21347/com.wgheng.test D/MyViewGroup: onMeasure:
06-30 08:30:51.779 21347-21347/com.wgheng.test D/MyViewGroup: onLayout:
06-30 08:30:51.779 21347-21347/com.wgheng.test D/MyViewGroup: onDraw: //绘制背景时回调了onDraw()
06-30 08:30:51.779 21347-21347/com.wgheng.test D/MyViewGroup: dispatchDraw:
Log中可以看到ViewGroup方法执行顺序和View唯一的差别在于,当ViewGroup绘制背景时会调用onDraw()方法,不绘制背景时就跳过onDraw()方法,执行dispatchDraw()方法
3. ViewGroup嵌套View时方法的执行顺序
1.xml文件中使用
<com.wgheng.test.MyViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#000000">
<com.wgheng.test.MyView
android:layout_width="100dp"
android:layout_height="100dp" />
</com.wgheng.test.MyViewGroup>
2.Log输出情况
06-30 10:20:16.872 8869-8869/com.wgheng.test D/MyViewGroup: MyViewGroup(2):
06-30 10:20:16.888 8869-8869/com.wgheng.test D/MyView: MyView(2):
06-30 10:20:16.890 8869-8869/com.wgheng.test D/MyView: onFinishInflate:
06-30 10:20:16.890 8869-8869/com.wgheng.test D/MyViewGroup: onFinishInflate:
06-30 10:20:16.973 8869-8869/com.wgheng.test D/MyViewGroup: onAttachedToWindow:
06-30 10:20:16.973 8869-8869/com.wgheng.test D/MyView: onAttachedToWindow:
06-30 10:20:16.976 8869-8869/com.wgheng.test D/MyViewGroup: onMeasure:
06-30 10:20:16.976 8869-8869/com.wgheng.test D/MyView: onMeasure:
06-30 10:20:17.078 8869-8869/com.wgheng.test D/MyViewGroup: onMeasure:
06-30 10:20:17.078 8869-8869/com.wgheng.test D/MyView: onMeasure:
06-30 10:20:17.078 8869-8869/com.wgheng.test D/MyViewGroup: onSizeChanged:
06-30 10:20:17.078 8869-8869/com.wgheng.test D/MyViewGroup: onLayout:
06-30 10:20:17.078 8869-8869/com.wgheng.test D/MyView: onSizeChanged:
06-30 10:20:17.078 8869-8869/com.wgheng.test D/MyView: onLayout:
06-30 10:20:17.103 8869-8869/com.wgheng.test D/MyViewGroup: onWindowFocusChanged:
06-30 10:20:17.103 8869-8869/com.wgheng.test D/MyView: onWindowFocusChanged:
06-30 10:20:17.107 8869-8869/com.wgheng.test D/MyViewGroup: onMeasure:
06-30 10:20:17.107 8869-8869/com.wgheng.test D/MyView: onMeasure:
06-30 10:20:17.107 8869-8869/com.wgheng.test D/MyViewGroup: onLayout:
06-30 10:20:17.107 8869-8869/com.wgheng.test D/MyView: onLayout:
06-30 10:20:17.108 8869-8869/com.wgheng.test D/MyViewGroup: onDraw: //仅当ViewGroup绘制背景时才执行
06-30 10:20:17.108 8869-8869/com.wgheng.test D/MyViewGroup: dispatchDraw:
06-30 10:20:17.108 8869-8869/com.wgheng.test D/MyView: onDraw:
06-30 10:20:17.108 8869-8869/com.wgheng.test D/MyView: dispatchDraw:
这个…看起来略乱,哈哈,就不总结了!