决定把一些Android容易说不清的面试题,仔细记录下
1.View是怎样测量的?
- View测量,一般是由其父容器ViewGroup发起的,ViewGroup.measureChildren遍历所有的子View,并依次对子View执行ViewGroup.measureChild
- ViewGroup.measureChild会计算出这个View粗略可以占用的宽高(widthMeasureSpec、heightMeasureSpec),将这个宽高传给View.measure方法
- View.measure(int widthMeasureSpec, int heightMeasureSpec)用来去计算更加精确的宽高,然后调用View.onMeasure执行最终设置宽高的操作
- View.onMeasure(int widthMeasureSpec, int heightMeasureSpec)中的setMeasuredDimension最终实现给View设置宽高
2.Android 事件是怎样分发的?
ActionDown事件传递路线:
-
=>屏幕
- =>Activity.dispatchTouchEvent 开始分发事件,分发给Window,如果Window处理不了则调自己的onTouchEvent
- =>Window.superDispatchTouchEvent() 什么也不干直接传给DocerView
- =>DocerView.superDispatchTouchEvent 什么也不干,直接调用父类的dispatchTouchEvent
- =>DocerView.super.dispatchTouchEvent 由于DocerView的父类是FrameLayout是ViewGroup
- =>ViewGroup.dispatchTouchEvent这里干很多事,1.决定是否拦截事件。2.找到事件指向的View
- =>ViewGroup.onInterceptTouchEvent 先判断是否需要拦截
- =>ViewGroup.dispatchTransformedTouchEvent 在循环对所有子View调用这个方法, 若面中加入TargetView单链表
- =>View.dispatchTouchEvent走到这里说明该View是被命中的TouchView
- =>View.onTouchEvent 如果该View没有Listener监听,没有onTouch回调就会走这里
ActionMove事件传递路线:
- =>屏幕
- =>Activity.dispatchTouchEvent 开始分发事件,分发给Window,如果Window处理不了则调自己的onTouchEvent
- =>Window.superDispatchTouchEvent() 什么也不干直接传给DocerView
- =>DocerView.superDispatchTouchEvent 什么也不干,直接调用父类的dispatchTouchEvent
- =>DocerView.super.dispatchTouchEvent 由于DocerView的父类是FrameLayout是ViewGroup
- =>ViewGroup.dispatchTouchEvent这里干很多事,1.决定是否拦截事件。
- =>ViewGroup.onInterceptTouchEvent 先判断是否需要拦截
- =>ViewGroup.dispatchTransformedTouchEvent 直接对TargetView单链表里所有的View调这个方法
- =>View.dispatchTouchEvent走到这里说明该View是刚才被命中的TouchView ,后续事件都给他
- =>View.onTouchEvent 如果该View没有Listener监听,没有onTouch回调就会走这里
ActionUp事件传递路线:
- =>屏幕
- =>Activity.dispatchTouchEvent 开始分发事件,分发给Window,如果Window处理不了则调自己的onTouchEvent
- =>Window.superDispatchTouchEvent() 什么也不干直接传给DocerView
- =>DocerView.superDispatchTouchEvent 什么也不干,直接调用父类的dispatchTouchEvent
- =>DocerView.super.dispatchTouchEvent 由于DocerView的父类是FrameLayout是ViewGroup
- =>ViewGroup.dispatchTouchEvent这里干很多事,1.决定是否拦截事件。
- =>ViewGroup.dispatchTransformedTouchEvent 直接对TargetView单链表里所有的View调这个方法
- =>View.dispatchTouchEvent走到这里说明该View是刚才被命中的TouchView
- =>View.onTouchEvent 如果该View没有Listener监听,没有onTouch回调就会走这里
- =>ViewGroup.dispatchTouchEvent 之后清空TargetView单链表