Android自定义view利用PathEffect实现动态效果

本文实例为大家分享了Android自定义view利用PathEffect实现动态效果的具体代码,供大家参考,具体内容如下

前言

在上一篇此类型的文章中是改变偏移量实现动态效果,借助的方法是drawArc,这篇文章依然是改变偏移量,而借助的是PathEffect的子类。

效果图:

Android自定义view利用PathEffect实现动态效果_第1张图片

一、首先介绍下PathEffect的一些子类

  • CornerPathEffect:将Path的各个连接线段之间的夹角用一种更平滑的方式连接,类似于圆弧与切线的效果。 参数radius则是指定圆弧的半径。
  • DashPathEffect:将Path的线段虚线化,intervals为虚线的ON和OFF的数组,数组中元素数目需要 >= 2; 而phase则为绘制时的偏移量。
  • DiscretePathEffect:打散Path的线段,使得在原来路径的基础上发生打散效果。 segmentLength指定最大的段长,deviation则为绘制时的偏离量。
  • PathDashPathEffect:使用Path图形来填充当前的路径,shape指的填充图形,advance是每个图形间的间隔, phase为绘制时的偏移量。,style则是该类自由的枚举值,有三种情况:ROTATE、MORPH和TRANSLATE。ROTATE情况下:线段连接处的图形转换以旋转到与下一段移动方向相一致的角度进行连接。MORPH情况下:图形会以发生拉伸或压缩等变形的情况与下一段相连接。TRANSLATE情况下:图形会以位置平移的方式与下一段相连接。
  • ComposePathEffect:组合效果
  • SumPathEffect:叠加效果,和ComposePathEffect不同,在表现时会将两个参数的效果都独立的表现出来, 接着将两个效果简单的重叠在一起显示出来

二、看看子类具体的一些代码

private static void makeEffects(PathEffect[] e, float phase) {
            e[0] = null;     // 无效果
            e[1] = new CornerPathEffect(30);//CornerPathEffect
            e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);//DashPathEffect
            e[3] = new PathDashPathEffect(makePathDash(), 12, phase,
                                          PathDashPathEffect.Style.ROTATE);//PathDashPathEffect
            e[4] = new ComposePathEffect(e[2], e[1]);//ComposePathEffect
            e[5] = new ComposePathEffect(e[3], e[1]);//ComposePathEffect
        }

三、案例实现(CornerPathEffect,PathDashPathEffect,ComposePathEffect)

实现的效果是上序代码的e[5],使用CornerPathEffect实现圆弧效果,而重点是PathDashPathEffect。

PathDashPathEffect里面有几个参数:

new PathDashPathEffect(makePathDash(), 12, phase,
         PathDashPathEffect.Style.ROTATE);

第一个参数为小path图形,案例中博主画的是菱形:

private static Path makePathDash() {
            Path p = new Path();
            p.moveTo(0, 0);
            p.lineTo(4, 4);
            p.lineTo(8, 0);
            p.lineTo(4, -4);
            p.moveTo(0, 0);
            return p;
        }

第二个参数为每个图形间的间隔。
第三个参数为绘制时的偏离量
第四个参数为样式,博主选择的是ROTATE情:线段连接处的图形转换以旋转到与下一段移动方向相一致的角度进行连接。

最后使用ComposePathEffect进行组合。

绘制运动路径

private static Path makeFollowPath() {
            Path p = new Path();
            p.moveTo(0, 0);
            p.lineTo(400,0);
            p.lineTo(400,400);
            p.lineTo(0,400);
            p.lineTo(0,0);
            return p;
        }

修改偏移量实现动态效果

mPhase += 1;
invalidate();

四、源码

public class SampleView extends View {
        private Paint mPaint;
        private Path mPath;
        private PathEffect[] mEffects;
        private int mColors;
        private float mPhase;


        private static void makeEffects(PathEffect[] e, float phase) {
            e[0] = null;     
            e[1] = new CornerPathEffect(30);
            e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);
            e[3] = new PathDashPathEffect(makePathDash(), 12, phase,
                                          PathDashPathEffect.Style.ROTATE);
            e[4] = new SumPathEffect(e[3], e[1]);
            e[5] = new ComposePathEffect(e[3], e[1]);
        }

        public SampleView(Context context) {
            super(context);
            setFocusable(true);
            setFocusableInTouchMode(true);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(6);
            mPath = makeFollowPath();
            //初始化PathEffect[]
            mEffects = new PathEffect[6];
            mColors = Color.BLACK;
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.WHITE);

            RectF bounds = new RectF();
            mPath.computeBounds(bounds, false);
            canvas.translate(10 - bounds.left, 10 - bounds.top);

            makeEffects(mEffects, mPhase);
            mPhase += 1;
            invalidate();

            //选择样式
            mPaint.setPathEffect(mEffects[5]);
            mPaint.setColor(mColors);
            canvas.drawPath(mPath, mPaint);
            canvas.translate(0, 28);

        }

        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_CENTER:
                    mPath = makeFollowPath();
                    return true;
            }
            return super.onKeyDown(keyCode, event);
        }
        //绘制跑动路径
        private static Path makeFollowPath() {
            Path p = new Path();
            p.moveTo(0, 0);
            p.lineTo(400,0);
            p.lineTo(400,400);
            p.lineTo(0,400);
            p.lineTo(0,0);
            return p;
        }
        //绘制跑动的小图标
        private static Path makePathDash() {
            Path p = new Path();
            p.moveTo(0, 0);
            p.lineTo(4, 4);
            p.lineTo(8, 0);
            p.lineTo(4, -4);
            p.moveTo(0, 0);
            return p;
        }
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

你可能感兴趣的