package com.anlia.progressbar; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; import android.widget.TextView; import com.anlia.utils.DpOrPxUtils; /** * Created by anlia on 2017/10/16. */ public class WaveProgressView extends View { private Paint circlePaint;//圆形进度框画笔 private Paint wavePaint;//绘制波浪画笔 private Path wavePath;//绘制波浪Path private Paint secondWavePaint;//绘制第二个波浪的画笔 private Bitmap bitmap;//缓存bitmap private Canvas bitmapCanvas; private WaveProgressAnim waveProgressAnim; private TextView textView; private OnAnimationListener onAnimationListener; private float waveWidth;//波浪宽度 private float waveHeight;//波浪高度 private int waveNum;//波浪组的数量(一次起伏为一组) private float waveMovingDistance;//波浪平移的距离 private int viewSize;//重新测量后View实际的宽高 private int defaultSize;//自定义View默认的宽高 private float percent;//进度条占比 private float progressNum;//可以更新的进度条数值 private float maxNum;//进度条最大值 private int waveColor;//波浪颜色 private int secondWaveColor;//第二层波浪颜色 private int bgColor;//背景进度框颜色 private boolean isDrawSecondWave; public WaveProgressView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context,attrs); } private void init(Context context,AttributeSet attrs){ TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.WaveProgressView); waveWidth = typedArray.getDimension(R.styleable.WaveProgressView_wave_width,DpOrPxUtils.dip2px(context,25)); waveHeight = typedArray.getDimension(R.styleable.WaveProgressView_wave_height,DpOrPxUtils.dip2px(context,5)); waveColor = typedArray.getColor(R.styleable.WaveProgressView_wave_color,Color.GREEN); secondWaveColor = typedArray.getColor(R.styleable.WaveProgressView_second_wave_color,getResources().getColor(R.color.light)); bgColor = typedArray.getColor(R.styleable.WaveProgressView_wave_bg_color,Color.GRAY); typedArray.recycle(); defaultSize = DpOrPxUtils.dip2px(context,100); waveNum =(int) Math.ceil(Double.parseDouble(String.valueOf(defaultSize / waveWidth / 2))); waveMovingDistance = 0; wavePath = new Path(); wavePaint = new Paint(); wavePaint.setColor(waveColor); wavePaint.setAntiAlias(true);//设置抗锯齿 wavePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); secondWavePaint = new Paint(); secondWavePaint.setColor(secondWaveColor); secondWavePaint.setAntiAlias(true);//设置抗锯齿 secondWavePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));//因为要覆盖在第一层波浪上,且要让半透明生效,所以选此模式 circlePaint = new Paint(); circlePaint.setColor(bgColor); circlePaint.setAntiAlias(true);//设置抗锯齿 waveProgressAnim = new WaveProgressAnim(); waveProgressAnim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) { /*if(percent == progressNum / maxNum){ waveProgressAnim.setDuration(5000); }*/ } }); percent = 0; progressNum = 0; maxNum = 100; isDrawSecondWave = false; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int height = measureSize(defaultSize, heightMeasureSpec); int width = measureSize(defaultSize, widthMeasureSpec); int min = Math.min(width, height);// 获取View最短边的长度 setMeasuredDimension(min, min);// 强制改View为以最短边为长度的正方形 viewSize = min; waveNum =(int) Math.ceil(Double.parseDouble(String.valueOf(viewSize / waveWidth / 2))); } private int measureSize(int defaultSize,int measureSpec) { int result = defaultSize; int specMode = View.MeasureSpec.getMode(measureSpec); int specSize = View.MeasureSpec.getSize(measureSpec); if (specMode == View.MeasureSpec.EXACTLY) { result = specSize; } else if (specMode == View.MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } return result; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); bitmap = Bitmap.createBitmap(viewSize, viewSize, Bitmap.Config.ARGB_8888); bitmapCanvas = new Canvas(bitmap); bitmapCanvas.drawCircle(viewSize/2, viewSize/2, viewSize/2, circlePaint); bitmapCanvas.drawPath(getWavePath(),wavePaint); if(isDrawSecondWave){ bitmapCanvas.drawPath(getSecondWavePath(),secondWavePaint); } canvas.drawBitmap(bitmap, 0, 0, null); } private Path getWavePath(){ // float changeWaveHeight = (1 - percent) * waveHeight; float changeWaveHeight = waveHeight; if(onAnimationListener!=null){ changeWaveHeight = onAnimationListener.howToChangeWaveHeight(percent,waveHeight) == 0 && percent < 1 ?waveHeight :onAnimationListener.howToChangeWaveHeight(percent,waveHeight); } wavePath.reset(); //移动到右上方,也就是p0点 wavePath.moveTo(viewSize, (1-percent)*viewSize); //移动到右下方,也就是p1点 wavePath.lineTo(viewSize, viewSize); //移动到左下边,也就是p2点 wavePath.lineTo(0, viewSize); //移动到左上方,也就是p3点 //wavePath.lineTo(0, (1-percent)*viewSize); wavePath.lineTo(-waveMovingDistance, (1-percent)*viewSize); //从p3开始向p0方向绘制波浪曲线 for (int i=0;i