Android PathEffects与ViewDragHelper的简单使用

Deadly 提交于 2019-12-27 15:20:13

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

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、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需要手动更新

优点:

  1. 避免了直接判断滑动方向,大小等

  2. 降低了代码复杂度,提高了编程效率

  3. 简化对滑动的理解,将【滚动驱动】转变为【滑动驱动】,避免了对【滚动方向】的理解

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


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!