Android PathEffects與ViewDragHelper的簡單使用

1.PathEffects是一種影響Canvas繪製線條的樣式工具。


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);
        }  
    }

2.使用ViewDragHelper建立SlidingMenu

ViewDragHelper的功能相似於ViewHelper,用來【滑動】View,不一樣點是ViewHelper的滑動會主動更新parentView,但ViewDragHelper須要手動更新java

優勢:編程

  1. 避免了直接判斷滑動方向,大小等canvas

  2. 下降了代碼複雜度,提升了編程效率dom

  3. 簡化對滑動的理解,將【滾動驅動】轉變爲【滑動驅動】,避免了對【滾動方向】的理解
    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);
        }
    }
}
相關文章
相關標籤/搜索