English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Android Implementation of Gradient Color Arc Dashed Line Effect

First, let's take a look at the effect picture:


1, SweepGradient(gradual rendering)

public SweepGradient (float cx, float cy, int[] colors, float[] positions)

Scanning rendering, which is the effect formed by rotating around a certain point center, is as follows:

      cx: the center x coordinate of the scan

      cy: the center y coordinate of the scan

      colors: the color array of gradient fade

      positions: specify the relative positions of the color array

public static final int[] SWEEP_GRADIENT_COLORS = new int[]{Color.GREEN, Color.GREEN, Color.BLUE, Color.RED, Color.RED};
mColorShader = new SweepGradient(radius, radius,SWEEP_GRADIENT_COLORS,null);

Effect picture:


SweepGradient

2, DashPathEffect(line segment dashed of Path)

DashPathEffect(float[] intervals, float phase)

      intervals: an array for the ON and OFF of the dashed line, the number of elements in the array must be >= 2

      phase: the offset amount during drawing

//Calculate the path length
PathMeasure pathMeasure = new PathMeasure(mPath, false);
float length = pathMeasure.getLength();
float step = length / 60;
dashPathEffect = new DashPathEffect(new float[]{step / 3, step * 2 / 3}, 0);

Effect picture:


DashPathEffect

3The following is all the code:

package com.example.yyw.xfermodedemo;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by yyw on 2016/10/11.
 */
public class OilTableLine extends View {
 public static final int[] SWEEP_GRADIENT_COLORS = new int[]{Color.GREEN, Color.GREEN, Color.BLUE, Color.RED, Color.RED};
 private int tableWidth = 50;
 private Paint mPaint;
 private Path mPath;
 private RectF mTableRectF;
 //Divide the path into dashed segments
 private DashPathEffect dashPathEffect;
 //Color the path
 private SweepGradient mColorShader;
 //The path of the pointer
 private Path mPointerPath;
 private float mCurrentDegree = 60;
 public OilTableLine(Context context, AttributeSet attrs) {
  super(context, attrs);
  mPaint = new Paint();
  mPaint.setAntiAlias(true);
  mPaint.setDither(true);
  mPaint.setColor(Color.BLACK);
  mPath = new Path();
  mPointerPath = new Path();
  startAnimator();
 }
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  float size = Math.min(w, h); - tableWidth * 2;
  //The oil gauge position frame
  mTableRectF = new RectF(0, 0, size, size);
  mPath.reset();
  //Add an arc from the starting angle to the oil gauge path
  mPath.addArc(mTableRectF, 60, 240);
  //Calculate the path length
  PathMeasure pathMeasure = new PathMeasure(mPath, false);
  float length = pathMeasure.getLength();
  float step = length / 60;
  dashPathEffect = new DashPathEffect(new float[]{step / 3, step * 2 / 3}, 0);
  float radius = size / 2;
  mColorShader = new SweepGradient(radius, radius,SWEEP_GRADIENT_COLORS,null);
  //Set the pointer path position
  mPointerPath.reset();
  mPointerPath.moveTo(radius, radius - 20);
  mPointerPath.lineTo(radius, radius + 20);
  mPointerPath.lineTo(radius * 2 - tableWidth, radius);
  mPointerPath.close();
 }
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  float dx = (getWidth() - mTableRectF.width()) / 2;
  float dy = (getHeight() - mTableRectF.height()) / 2;
  //Translate the oil gauge box to the center
  canvas.translate(dx, dy);
  canvas.save();
  //Rotate the canvas
  canvas.rotate(90, mTableRectF.width() / 2, mTableRectF.height() / 2);
  mPaint.setStyle(Paint.Style.STROKE);
  mPaint.setStrokeWidth(tableWidth);
  mPaint.setPathEffect(dashPathEffect);
  mPaint.setShader(mColorShader);
  canvas.drawPath(mPath, mPaint);
  canvas.restore();
  //Restore the brush
  mPaint.setPathEffect(null);
  mPaint.setShader(null);
  mPaint.setStyle(Paint.Style.FILL);
  mPaint.setStrokeWidth(tableWidth / 10);
  canvas.save();
  canvas.rotate(150 + mCurrentDegree, mTableRectF.width() / 2, mTableRectF.height() / 2);
  canvas.drawPath(mPointerPath, mPaint);
  canvas.restore();
 }
 public void startAnimator() {
  ValueAnimator animator = ValueAnimator.ofFloat(0, 240);
  animator.setDuration(40000);
  animator.setRepeatCount(ValueAnimator.INFINITE);
  animator.setRepeatMode(ValueAnimator.RESTART);
  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
    mCurrentDegree = (int) (0 + (Float) animation.getAnimatedValue());
    invalidate();
   }
  });
  animator.start();
 }
}

Summary

That's all for this article. I hope the content of this article can bring some help to your learning or work. If you have any questions, you can leave a message for communication.

You May Also Like