Android渐变色的圆弧虚线

Draco 7年前
   <p>在学习Android的paint类的时候学习了 PathEffect 路径效果和 Shader 渲染效果。做了下面的一个效果的自定义的view组主要是用DashPathEffect、SweepGradient的API形成的效果。下面是效果图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f57a049634cffaa424a39e65f0e5d4e6.png"></p>    <p style="text-align:center">Android渐变色的圆弧虚线</p>    <p><strong>1,SweepGradient(梯度渲染)</strong></p>    <p><strong>public SweepGradient (float cx, float cy, int[] colors, float[] positions)</strong></p>    <p>扫描渲染,就是以某个点位中心旋转一周所形成的效果!参数依次是:</p>    <p><strong>cx:</strong>扫描的中心x坐标</p>    <p><strong>cy:</strong>扫描的中心y坐标</p>    <p><strong>colors:</strong>梯度渐变的颜色数组</p>    <p><strong>positions:</strong>指定颜色数组的相对位置</p>    <pre>  <code class="language-java">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);</code></pre>    <p>效果图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/1ab8a94df521339fe4f125a0980ed3d5.png"></p>    <p style="text-align:center">SweepGradient</p>    <p><strong>2,DashPathEffect(Path的线段虚线化)</strong></p>    <p><strong>DashPathEffect(float[] intervals, float phase)</strong></p>    <p><strong>intervals:</strong>为虚线的ON和OFF的数组,数组中元素数目需要 >= 2</p>    <p><strong>phase:</strong>为绘制时的偏移量</p>    <pre>  <code class="language-java">//计算路径的长度  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);</code></pre>    <p>效果图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/2c7d13c5057e28d7489e756cc7208c5a.png"></p>    <p style="text-align:center">DashPathEffect</p>    <p><strong>3,下面是全部的代码:</strong></p>    <pre>  <code class="language-java">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;      //把路径分成虚线段的      private DashPathEffect dashPathEffect;      //给路径上色      private SweepGradient mColorShader;      //指针的路径      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;          //油表的位置方框          mTableRectF = new RectF(0, 0, size, size);          mPath.reset();          //在油表路径中增加一个从起始弧度          mPath.addArc(mTableRectF, 60, 240);          //计算路径的长度          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);          //设置指针的路径位置          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;          //把油表的方框平移到正中间          canvas.translate(dx, dy);          canvas.save();          //旋转画布          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();          //还原画笔          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();      }  }</code></pre>    <p> </p>    <p>来自:http://www.jianshu.com/p/92bf75e41fff</p>    <p> </p>