public class PathEffectView extends View { float phase; PathEffect[] effects = new PathEffect[7]; int[] colors; private Paint paint; Path path; public PathEffectView(Context context) { this(context, null); } public PathEffectView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public PathEffectView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); paint = new Paint(); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(4); // 建立、並初始化Path path = new Path(); path.moveTo(0, 0); for (int i = 1; i <= 15; i++) { // 生成15個點,隨機生成它們的Y座標。並將它們連成一條Path path.lineTo(i * 20, (float) Math.random() * 60); } // 初始化7個顏色 colors = new int[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA, Color.RED, Color.YELLOW }; // -----------下面開始初始化7中路徑效果---------- // 不使用路徑效果。 effects[0] = null; // 使用CornerPathEffect路徑效果 effects[1] = new CornerPathEffect(10); // 初始化DiscretePathEffect effects[2] = new DiscretePathEffect(3.0f, 5.0f); } @Override protected void onDraw(Canvas canvas) { // 將背景填充成白色 canvas.drawColor(Color.WHITE); // 初始化DashPathEffect,DashPathEffect有動畫效果 effects[3] = new DashPathEffect(new float[] { 20, 10, 5, 10 }, phase); // 初始化PathDashPathEffect,PathDashPathEffect有動畫效果 Path p = new Path(); p.addRect(0, 0, 8, 8, Path.Direction.CCW); effects[4] = new PathDashPathEffect(p, 12, phase, PathDashPathEffect.Style.ROTATE); // 初始化PathDashPathEffect effects[5] = new ComposePathEffect(effects[2], effects[4]); effects[6] = new SumPathEffect(effects[4], effects[3]); // 對Canvas執行座標變換:將畫布「總體位移」到八、8處開始繪製 canvas.translate(8, 8); // 依次使用7中不一樣路徑效果、7種不一樣的顏色來繪製路徑 for (int i = 0; i < effects.length; i++) { paint.setPathEffect(effects[i]); paint.setColor(colors[i]); canvas.drawPath(path, paint); canvas.translate(0, 60); } canvas.restore(); // 改變phase值,造成動畫效果 phase += 1; Log.i("SSSSS","SSSS===>"+phase); postInvalidateDelayed(50); } }
ViewDragHelper的功能相似於ViewHelper,用來【滑動】View,不一樣點是ViewHelper的滑動會主動更新parentView,但ViewDragHelper須要手動更新java
優勢:編程
避免了直接判斷滑動方向,大小等canvas
下降了代碼複雜度,提升了編程效率dom
簡化對滑動的理解,將【滾動驅動】轉變爲【滑動驅動】,避免了對【滾動方向】的理解
ide
public class DragViewGrop extends FrameLayout { private View mMenuView; private View mContentView; private ViewDragHelper mViewDragHelper; private int mMenuWidth; public DragViewGrop(Context context) { this(context, null); } public DragViewGrop(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DragViewGrop(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mViewDragHelper = ViewDragHelper.create(this,mViewDragHelperCallback); } @Override protected void onFinishInflate() { super.onFinishInflate(); mMenuView = getChildAt(0); mContentView = getChildAt(1); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mMenuWidth = mMenuView.getMeasuredWidth(); } @Override public boolean onTouchEvent(MotionEvent event) { mViewDragHelper.processTouchEvent(event); //將事件交由onTouchEvent處理 return true; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mViewDragHelper.shouldInterceptTouchEvent(ev); } private ViewDragHelper.Callback mViewDragHelperCallback = new ViewDragHelper.Callback(){ public boolean tryCaptureView(View child, int pointerId){ return child==mContentView; } @Override public void onViewDragStateChanged(int state) { if(state==ViewDragHelper.STATE_IDLE) { Log.i("STATE","中止滑動!"); } super.onViewDragStateChanged(state); } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { return Math.min(mMenuWidth * 2 / 3,Math.max(left,0)); //橫向滑動,注意範圍控制 } @Override public int clampViewPositionVertical(View child, int top, int dy) { return 0; } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { super.onViewReleased(releasedChild, xvel, yvel); if(mContentView.getLeft()<(mMenuWidth/2)*2/3) { mViewDragHelper.smoothSlideViewTo(mContentView,0,0); ViewCompat.postInvalidateOnAnimation(DragViewGrop.this); }else{ mViewDragHelper.smoothSlideViewTo(mContentView,mMenuWidth*2/3,0); ViewCompat.postInvalidateOnAnimation(DragViewGrop.this); } } }; @Override public void computeScroll() { super.computeScroll(); //使用消息隊列發送狀態數據到Callback.onViewDragStateChanged,並判斷是否仍然在滑動 if(mViewDragHelper.continueSettling(true)) { //ViewCompat用來刷新當前佈局,不然滑動效果沒法顯示,能夠替換成invalidate()或者postInvalidate() ViewCompat.postInvalidateOnAnimation(DragViewGrop.this); } } }