Android SweepGradient 扫描渲染

概述

记的之前看到一个通过扫描渲染实现的雷达效果UI。自己在复习shader,在此做一个记录。

SweepGradient 扫描渐变

构造函数参数说明

  public SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1)

参数(cx,cy)表示扫描渲染所围绕的圆心点坐标,color0 代表渲染的起始颜色,color1代表渲染的结束颜色。

 public SweepGradient(float cx, float cy,
            @NonNull @ColorInt int colors[], @Nullable float positions[]) {

参数(cx,cy)表示扫描渲染所围绕的圆心点坐标,colors数组代表扫描渐变的颜色数组,数组值大于2,第一位数组值代表起始颜色,最后一位代表结束颜色,positinos 数组,每一位值与颜色数组相对应,代表该颜色的渲染起始位置(360*positions[i],具体效果参看示列代码运行效果图。

雷达扫描效果

借助动画和matrix类不断旋转shader的默认颜色渲染角度,形成雷达扫描效果。

示例代码

扫描渲染view

package com.xol.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.SweepGradient;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.xol.util.CommonUtil;

/**
 * Created by wwzhang on 2019/3/20
 */
public class SweepGradientView extends View {
    private Paint mPaint;
    private int[] mColorArrayTwo;
    private int[] mColorArrayThree;
    private SweepGradient mSweepGradient;

    public SweepGradientView(Context context) {
        super(context);
    }

    public SweepGradientView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public SweepGradientView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mColorArrayTwo = new int[]{Color.parseColor("#ff0000"),
                Color.parseColor("#ffffff")};
        mColorArrayThree = new int[]{Color.parseColor("#ff0000")
                , Color.parseColor("#00ff00")
                , Color.parseColor("#0000ff")};

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制圆形
        mPaint.setStyle(Paint.Style.FILL);
        mSweepGradient = new SweepGradient(200, 200, mColorArrayTwo[0], mColorArrayTwo[1]);
        mPaint.setShader(mSweepGradient);
        canvas.drawCircle(200, 200, 100, mPaint);
        //绘制圆形
        mSweepGradient = new SweepGradient(500, 600, mColorArrayThree, new float[]{0.0f, 0.5f, 1.0f});
        mPaint.setStrokeWidth(CommonUtil.dp2px(4, getContext()));
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setShader(mSweepGradient);
        canvas.drawCircle(500, 600, 200, mPaint);
        //绘制圆形
        mSweepGradient = new SweepGradient(500, 1000, mColorArrayThree, new float[]{0.5f, 0.75f, 1.0f});
        mPaint.setShader(mSweepGradient);
        canvas.drawCircle(500, 1000, 200, mPaint);

    }
}

雷达扫描view

package com.xol.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.xol.util.CommonUtil;

/**
 * Created by wwzhang on 2019/3/21
 */
public class RadarView extends View {

    private Paint mPaint;
    private int mCircleColor;
    private int mSweepColor[];
    private float mCenterY;
    private float mCenterX;
    private float mRadius;
    private int mPading;
    private Shader mSweepShader;
    private ValueAnimator mValueAnimator;
    private Matrix mRoateMatrix;
    private float mDegressProgress = 0.2f;

    public RadarView(Context context) {
        super(context);
    }

    public RadarView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    private static final String TAG = "RadarView";

    public RadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mRoateMatrix = new Matrix();
        mCircleColor = Color.parseColor("#000000");
        mSweepColor = new int[]{Color.parseColor("#0000ff"),
                Color.parseColor("#22000000")};
        mPaint.setStrokeWidth(CommonUtil.dp2px(2, getContext()));
        mRadius = -1;
        mPading = (int) CommonUtil.dp2px(10, getContext());
        mValueAnimator = ValueAnimator.ofFloat(0, 1.0f);
        mValueAnimator.setInterpolator(new LinearInterpolator());
        mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        mValueAnimator.setDuration(5000);
        mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mDegressProgress = (float) animation.getAnimatedValue();
                Log.d(TAG, "onAnimationUpdate: " + mDegressProgress);
                invalidate();
            }
        });
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mRadius < 0) {
            int minDistance = Math.min(getMeasuredHeight(), getMeasuredWidth());
            mCenterX = minDistance / 2;
            mCenterY = mCenterX;
            mRadius = mCenterX - mPading;
            mSweepShader = new SweepGradient(mCenterX, mCenterY, mSweepColor[0], mSweepColor[1]);
        }
        //绘制扫描线
        canvas.save();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setShader(mSweepShader);
        mRoateMatrix.setRotate(mDegressProgress * 360,mCenterX,mCenterY);
        mSweepShader.setLocalMatrix(mRoateMatrix);
        // canvas.rotate(mDegressProgress * 360, mCenterX, mCenterY);
        canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
        canvas.restore();
        //绘制圆形和直角坐标
        mPaint.setColor(mCircleColor);
        mPaint.setShader(null);
        canvas.save();
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
        canvas.drawCircle(mCenterX, mCenterY, mRadius / 2, mPaint);
        canvas.drawLine(mPading, mCenterY, mCenterX + mRadius, mCenterY, mPaint);
        canvas.drawLine(mCenterX, mPading, mCenterX, mCenterY + mRadius, mPaint);
        canvas.restore();
        if (!mValueAnimator.isStarted()) {
            mValueAnimator.start();
        }

    }


    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        Log.d(TAG, "onAttachedToWindow: ");
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.d(TAG, "onDetachedFromWindow: ");
        if (mValueAnimator.isStarted()) {
            mValueAnimator.cancel();
        }
    }
}

布局文件




    

    


运行效果

Android SweepGradient 扫描渲染_第1张图片
希望对您有所帮助!

你可能感兴趣的:(android)