This is the 23rd day of my participation in the August More Text Challenge.More challenges in August

Series of articles

Android custom view using PathEffect dynamic effect


There is source code at the end of the article


preface

In the last article of this type, we changed the offset to achieve dynamic effects, using drawArc. In this article, we still change the offset, using a subclass of PathEffect.

Effect:


First, introduce some subclasses of PathEffect

  • CornerPathEffect: Connects the corners of the connected line segments of your Path in a smoother way, similar to arcs and tangents. The radius parameter specifies the radius of the arc.

  • DashPathEffect: Dash the Path segments. The intervals are an array of dashed lines ON and OFF. The number of elements in the array must be >= 2. Phase is the offset at drawing time.

  • DiscretePathEffect: break up the Path segment, on the basis of the original Path scatter effect. SegmentLength specifies the maximum section length, and deviation refers to the deviation amount when drawing.

  • PathDashPathEffect: Fill the current Path with a Path graph. Shape refers to the fill graph, advance is the interval between each graph, and phase is the offset when drawing. ROTATE, MORPH, and TRANSLATE are the free enumerations of this class. ROTATE: A graph at a line segment connection is rotated to an Angle consistent with the movement direction of the next segment. In MORPH case: the graph will be connected with the next section in the case of stretching or compression. TRANSLATE: The shape is translated to the next paragraph.

  • ComposePathEffect: Combined effects

  • SumPathEffect: Superimposed effects. Unlike ComposePathEffect, the effects of both parameters are displayed independently and then simply superimposed together

Look at some of the code for subclasses

        private static void makeEffects(PathEffect[] e, float phase) {
            e[0] = null;     / / no results
            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
        }
Copy the code

Iii. Case implementation (Corner on the ffect, Pathon the ffect, composeon the ffect)

The effect implemented is e of the upper-order code [5], with a CornerPathEffect for the arc effect, with the emphasis on PathDashPathEffect.

There are several parameters in PathDashPathEffect:

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

The first parameter is a small path graph. In this case, the blogger drew a diamond:

        private static Path makePathDash(a) {
            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;
        }
Copy the code

The second parameter is the interval between each figure. The third parameter is the amount of deviation when drawing and the fourth parameter is the style. The blogger selects the ROTATE case: The graph transformation at the connection of line segments is connected by rotation to an Angle consistent with the direction of the next segment. Finally, use posepa ect for combination.

Draw the path of motion

        private static Path makeFollowPath(a) {
            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;
        }
Copy the code

Modify offset to achieve dynamic effect

    mPhase += 1;
    invalidate();
Copy the code

Four source

    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();
            // Initialize 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();

            // Select the style
            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);
        }
        // Draw the running path
        private static Path makeFollowPath(a) {
            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;
        }
        // Draw a small icon for running
        private static Path makePathDash(a) {
            Path p = new Path();
            p.moveTo(0.0);
            p.lineTo(4.4);
            p.lineTo(8.0);
            p.lineTo(4, -4);
            p.moveTo(0.0);
            returnp; }}Copy the code