一. 對於控件,Android中的測量方式android
在Android中,控件繪製的步驟是 measure,layout,drawide
//在onMeasure調用以前調用的測量方式 private void measureView(View child) { ViewGroup.LayoutParams p = child.getLayoutParams(); if (p == null) { p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } //根據父佈局得到child寬度的建議大小 int childWidthSpec = ViewGroup.getChildMeasureSpec(0, mListPadding.left + mListPadding.right, p.width); //高度不是固定的,可能比父佈局高,所以不該該調動ViewGroup.getChildMeasureSpec int lpHeight = p.height; int childHeightSpec; if (lpHeight > 0) { childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); //精確高度 } else { childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); //要多大有多大 } child.measure(childWidthSpec, childHeightSpec); }
通常來講,若是父佈局的寬度和高度,內外邊距位指定,那麼,上面的方法能夠簡化以下佈局
private void measureView(View child) { child.measure(0, 0); }
在android開發中,經常使用的測量方法還有 measureChildren(); measureChildpost
手指一動的最小距離獲取應該大於ViewConfiguration.getScaledTouchSlop ()纔開始滑動spa
注:ViewConfiguration註冊了各類滑動和觸摸的最小距離.net
通常來講在onCreate中沒法獲得控件的高度,除非設定成已知數據,或者已對控件進行測量,但getWidth不必定是已知的,只能獲得getMeasureWidthcode
通常來講有以下幾種獲取方式orm
@Override public void onWindowFocusChanged(boolean hasFocus) { View iv1 = findViewById(R.id.iv1); View iv2=findViewById(R.id.iv2); String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+" measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight(); String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+" measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight(); i("onWindowFocusChanged() "+msg1); i("onWindowFocusChanged() "+msg2); super.onWindowFocusChanged(hasFocus); }
或者以下,imageView徹底被繪製出展現server
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { view.postDelayed(new Runnable() { @Override public void run() { View iv1 = findViewById(R.id.iv1); View iv2=findViewById(R.id.iv2); String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+" measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight(); String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+" measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight(); i("onWindowFocusChanged() "+msg1); i("onWindowFocusChanged() "+msg2); } }, 300); } });
Android中對於事件的操做,主要集中於3個方法,dispatchTouchEvent, onInteceptorTouchEvent(ViewGroup獨有), onTouchEvent,其中,傳遞方向有2個blog
Activity->Window->ViewGroup->...->childView[--->分發攔截階段 Activity<-Window<-ViewGroup<-...<-childView[--->處理階段
分發攔截階段,dispatchTouchEvent會調用onInteceptorTouchEvent進行判斷,是否繼續傳遞,若是onInteceptorTouchEvent返回值爲ture,
表示直接中止分發,把事件交由onTouchEvent進行處理;不然想tragetview傳遞,childview調用dispatchTouchEvent進行相似判斷
處理階段,徹底由onTouchEvent進行處理,返回值爲ture,終止事件回傳
注意:調用requestDisallowInterceptTouchEvent(true)時,onInteceptorTouchEvent不會被調用,詳情請看源碼
DecorView爲頂級View,DecoreView分爲2部分,第一部分是Title,第二部分是Content,對應的ID分別爲R.Android.id.title和R.android.id.content
view 的繪製流程從 ViewRoot 的 performTraversals 開始,代碼流程是這樣的:
performMeasure -> measure -> onMeasure
performLayout -> layout -> onLayout
performDraw -> draw -> onDraw
View內部的繪製流程
view的繪製大體遵循以下流程:先繪製背景,再繪製本身(onDraw),接着繪製子元素(dispatchDraw),最後繪製一些裝飾等好比滾動條(onDrawScrollBars)
參考:http://blog.csdn.net/singwhatiwanna/article/details/42614953