1、重寫onMeasure()方法的目的:
重寫onMeasure()方法的目的就是為了設(shè)置Wrap_content的情況下View的寬和高的值。
因為在View類的oMeasure()方法中的getDefaultSize()方法中MeasureSpec為EXACTLY和AT_MOST兩種情況返回的size都為specSize(MeasureSpec.getSize(measureSpec))
而specSize即為父布局所剩余的size
specSize又是ViewGroup通過measureChildWithMargin()方法中的getChildMeasureSpec()中計算出來封存到MeasureSpec中的
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec , heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpceSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode=MeasureSpec.getMode(heightMeasureSpec);
int heightSpceSize=MeasureSpec.getSize(heightMeasureSpec);
if(widthSpecMode==MeasureSpec.AT_MOST&&heightSpecMode==Mea sureSpec.AT_MOST){
setMeasuredDimension(mWidth, mHeight);
}else if(widthSpecMode==MeasureSpec.AT_MOST){
setMeasuredDimension(mWidth, heightSpceSize);
}else if(heightSpecMode==MeasureSpec.AT_MOST){
setMeasuredDimension(widthSpceSize, mHeight);
}
}
2、invalidate()和postInvalidate()
- invalidate() 主線程中調(diào)用
- postInvalidate()子線程中調(diào)用,內(nèi)部實現(xiàn)是handler發(fā)送延遲消息,最終還是調(diào)用了invalidate()
3、事件分發(fā)機制
其實事件分發(fā)機制,可以分為兩個過程,一個是向下分發(fā)過程,一個是向上返回過程,其中向下分發(fā)是靠dispatchTouchEvent 方法,從Activity的dispatchTouchEvent 直到目標(biāo)視圖的dispatchTouchEvent ,然后進入目標(biāo)視圖的onTouchEvent,向上返回則是靠onTouchEvent,從目標(biāo)視圖的onTouchEvent直到Activity的onTouchEvent。
而在向下分發(fā)的過程可能會提前結(jié)束,這受onInterceptTouchEvent影響,也可能是ViewGroup沒有子視圖了,在兩個因素都可以使該過程提前結(jié)束,從而提前進入向上返回的過程。向上返回過程也可能提前結(jié)束,如果事件在onTouchEvent中返回true,即事件被消費,那么事件不會繼續(xù)向上傳遞,該過程提前結(jié)束。