郭孝星,程序员,吉他手,主要从事Android平台基础架构方面的工作,欢迎交流技术方面的问题,可以去我的Github提issue或者发邮件至guoxiaoxingse@163.com与我交流。
第一次阅览本系列文章,请参见导读,更多文章请参见文章目录。
文章目录
This class represents the basic building block for user interface components. A Viewoccupies a rectangular area on the screen and is
responsible for drawing and event handling.
View是屏幕上的一块矩形区域,负责界面的绘制与触摸事件的处理,它是一种界面层控件的抽象,所有的控件都继承自View。
View是Android显示框架中较为复杂的一环,首先是它的生命周期会随着Activity的生命周期进行变化,掌握View的生命周期对我们自定义View有着重要的意义。另一个方面View从ViewRoot.performTraversals()开始
经历measure、layout、draw三个流程最终显示在用户面前,用户在点击屏幕时,点击事件随着Activity传入Window,最终由ViewGroup/View进行分发处理。今天我们就围绕着这些主题进行展开分析。
在View中有诸多回调方法,它们在View的不同生命周期阶段调用,常用的有以下方法。
我们写一个简单的自定义View来观察View与Activity的生命周期变化。
- public
- class
- CustomView
- extends
- View
- {
- private static final String TAG = "View";
- public CustomView(Context context) {
- super(context);
- Log.d(TAG, "CustomView()");
- }
- public CustomView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- Log.d(TAG, "CustomView()");
- }
- public
- CustomView
- (Context context, @Nullable AttributeSet attrs, int defStyleAttr)
- {
- super(context, attrs, defStyleAttr);
- Log.d(TAG, "CustomView()");
- }
- /**
- * View在xml文件里加载完成时调用
- */
- @Override
- protected
- void
- onFinishInflate
- ()
- {
- super.onFinishInflate();
- Log.d(TAG, "View onFinishInflate()");
- }
- /**
- * 测量View及其子View大小时调用
- */
- @Override
- protected
- void
- onMeasure
- (int widthMeasureSpec, int heightMeasureSpec)
- {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- Log.d(TAG, "View onMeasure()");
- }
- /**
- * 布局View及其子View大小时调用
- */
- @Override
- protected
- void
- onLayout
- (
- boolean
- changed,
- int
- left,
- int
- top,
- int
- right,
- int
- bottom)
- {
- super.onLayout(changed, left, top, right, bottom);
- Log.d(TAG, "View onLayout() left = " + left + " top = " + top + " right = " + right + " bottom = " + bottom);
- }
- /**
- * View大小发生改变时调用
- */
- @Override
- protected
- void
- onSizeChanged
- (
- int
- w,
- int
- h,
- int
- oldw,
- int
- oldh)
- {
- super.onSizeChanged(w, h, oldw, oldh);
- Log.d(TAG, "View onSizeChanged() w = " + w + " h = " + h + " oldw = " + oldw + " oldh = " + oldh);
- }
- /**
- * 绘制View及其子View大小时调用
- */
- @Override
- protected
- void
- onDraw
- (Canvas canvas)
- {
- super.onDraw(canvas);
- Log.d(TAG, "View onDraw()");
- }
- /**
- * 物理按键事件发生时调用
- */
- @Override
- public
- boolean
- onKeyDown
- (int keyCode, KeyEvent event)
- {
- Log.d(TAG, "View onKeyDown() event = " + event.getAction());
- return super.onKeyDown(keyCode, event);
- }
- /**
- * 物理按键事件发生时调用
- */
- @Override
- public
- boolean
- onKeyUp
- (int keyCode, KeyEvent event)
- {
- Log.d(TAG, "View onKeyUp() event = " + event.getAction());
- return super.onKeyUp(keyCode, event);
- }
- /**
- * 触摸事件发生时调用
- */
- @Override
- public
- boolean
- onTouchEvent
- (MotionEvent event)
- {
- Log.d(TAG, "View onTouchEvent() event = " + event.getAction());
- return super.onTouchEvent(event);
- }
- /**
- * View获取焦点或者失去焦点时调用
- */
- @Override
- protected
- void
- onFocusChanged
- (boolean gainFocus, int direction, @Nullable Rect previouslyFocusedRect)
- {
- super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
- Log.d(TAG, "View onFocusChanged() gainFocus = " + gainFocus);
- }
- /**
- * View所在窗口获取焦点或者失去焦点时调用
- */
- @Override
- public
- void
- onWindowFocusChanged
- (boolean hasWindowFocus)
- {
- super.onWindowFocusChanged(hasWindowFocus);
- Log.d(TAG, "View onWindowFocusChanged() hasWindowFocus = " + hasWindowFocus);
- }
- /**
- * View被关联到窗口时调用
- */
- @Override
- protected
- void
- onAttachedToWindow
- ()
- {
- super.onAttachedToWindow();
- Log.d(TAG, "View onAttachedToWindow()");
- }
- /**
- * View从窗口分离时调用
- */
- @Override
- protected
- void
- onDetachedFromWindow
- ()
- {
- super.onDetachedFromWindow();
- Log.d(TAG, "View onDetachedFromWindow()");
- }
- /**
- * View的可见性发生变化时调用
- */
- @Override
- protected
- void
- onVisibilityChanged
- (@NonNull View changedView, int visibility)
- {
- super.onVisibilityChanged(changedView, visibility);
- Log.d(TAG, "View onVisibilityChanged() visibility = " + visibility);
- }
- /**
- * View所在窗口的可见性发生变化时调用
- */
- @Override
- protected
- void
- onWindowVisibilityChanged
- (int visibility)
- {
- super.onWindowVisibilityChanged(visibility);
- Log.d(TAG, "View onWindowVisibilityChanged() visibility = " + visibility);
- }
- }
Activity与View的生命周期变化一目了然。
Activity create
Activity pause
Activity resume
Activity destory
我们来总结一下View的声明周期随着Activity生命周期变化的情况。
我们了解这些生命周期方法有什么作用呢?
来源: https://juejin.im/post/5a1e8d5ef265da431280ae19