No1: View的滑動 1)layout()方法的 2)offsetLeftAndRight()與offsetTopAndBottom() 對上面代碼進行修改 3)LayoutParams(改變佈局參數) 同樣對上面代碼進行修改 4)動畫 5)scrollTo與scrollBy scrollTo( ...
No1:
View的滑動
1)layout()方法的
public class CustomView extends View{ private int lastX; private int lastY; public CustomView(Context context,AttributeSet attrs,int defStyleAttr){ super(context,attrs,defStyleAttr); } public CustomView(Context context,AttributeSet attrs){ super(context,attrs); } public CustomView(Context context){ super(context); } public boolean onTouchEvent(MotionEvent event){ //獲取手指摸點的橫坐標和縱坐標 int x = (int)event.getX(); int y = (int)event.getY(); switch(event.getAction()){ case MotionEvent.ACTION_DOWN: lastX = x; lastY = y; break; case MotionEvent.ACTION_MOVE: //計算移動的距離 int offsetX = x - lastX; int offsetY = y - lastY; //調用layout方法來重新放置它的位置 layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY); break; } return true; } }
2)offsetLeftAndRight()與offsetTopAndBottom()
對上面代碼進行修改
case MotionEvent.ACTION_MOVE: //計算移動的距離 int offsetX = x - lastX; int offsetY = y - lastY; //對left和right進行偏移 offsetLeftAndRight(offsetX); //對top和bottom進行偏移 offsetTopAndBottom(offsetY); break;
3)LayoutParams(改變佈局參數)
同樣對上面代碼進行修改
case MotionEvent.ACTION_MOVE: ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)getLayoutParams(); layoutParams.leftMargin = getLeft() + offsetX; layoutParams.topMargin = getTop() + offsetY; setLayoutParams(layoutParams); break;
4)動畫
5)scrollTo與scrollBy
scrollTo(x,y)表示移動到一個具體的坐標點,而scrollBy(x,y)表示移動的增量為dx、dy。其中scrollBy最終也是要調用scrollTo的。
View.java的scrollBy和scrollTo源碼
public void scrollTo(int x,int y){ if(mScrollX!=x || mScrollY!=y){ int oldX = mScrollX; int oldY = mScrollY; mScrollX = x; mScrollY = y; invalidateParentCaches(); onScrollChanged(mScrollX,mScrollY,oldX,oldY); if(!awakenScrollBars()){ postInvalidateOnAnimation(); } } } public void scrollBy(int x,int y){ scrollTo(mScrollX+x,mScrollY+y); }
6)Scroller
public CustomView(Context context,AttributeSet attrs){ super(context,attrs); mScroller = new Scroller(context); } @Override public void computeScroll(){ super.computeScroll(); if(mScroller.computeScrollOffset()){ ((View)getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY()); invalidate(); } } public void smoothScrollTo(int destX,int destY){ int scrollX = getScrollX(); int delta = destX-scrollX; mScroller.startScroll(scrollX,0,delta,0,2000); invalidate(); } //最後調用 mCustomView.smoothScrollTo(-400,0);
No2:
View的measure流程,ViewGroup中定義了measureChildren方法
View和ViewGroup中均沒有實現onLayout方法
No3:
View的draw流程
1)繪製背景:View.drawBackground()
2)繪製View的內容:重寫View.onDraw()
3)繪製子View:ViewGroup.dispatchDraw()對子View進行遍歷->ViewGroup.drawChild()->View.draw()
4)繪製裝飾:View.onDrawForeground()
No4:
自定義View
1)繼承系統控制項的自定義View:重寫onDraw()
2)繼承View的自定義View:重寫onDraw()、考慮warp_content屬性以及padding屬性設置、或者自定義屬性、考慮是否重寫onTouchEvent()
3)自定義組合控制項
4)自定義ViewGroup:重寫onLayout()、處理warp_content屬性、處理滑動衝突、彈性滑動到其他頁面、快速滑動到其他頁面、再次觸摸屏幕阻止頁面繼續滑動