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

Posted 计蒙不吃鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自定义view之利用PathEffect实现动态效果相关的知识,希望对你有一定的参考价值。

系列文章目录

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


文章最后有源码


前言

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


一、首先介绍下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;
        }
    }

以上是关于Android自定义view之利用PathEffect实现动态效果的主要内容,如果未能解决你的问题,请参考以下文章

自定义View 之利用ViewPager 实现画廊效果(滑动放大缩小)

自定义View 之利用ViewPager 实现画廊效果(滑动放大缩小)

android自定义控件怎么用

Android开发之利用SQLite进行数据存储

自定义Groupview添加子view的问题

Android自定义View实现可拖拽的进度条