308 lines
9.0 KiB
Java
308 lines
9.0 KiB
Java
package com.xuebiping.bolizhuzi.utils;
|
||
|
||
import android.content.Context;
|
||
import android.graphics.Canvas;
|
||
import android.graphics.Paint;
|
||
import android.util.AttributeSet;
|
||
import android.view.View;
|
||
import android.view.animation.Interpolator;
|
||
import android.view.animation.LinearInterpolator;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.Iterator;
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 水波纹扩散效果
|
||
* https://github.com/hackware1993/WaveView
|
||
*/
|
||
public class WaveView extends View {
|
||
|
||
private float mInitialRadius; // 初始波纹半径
|
||
private float mMaxRadius; // 最大波纹半径
|
||
private long mDuration = 3000; // 一个波纹从创建到消失的持续时间
|
||
private int mSpeed = 1000; // 波纹的创建速度,每500ms创建一个
|
||
private float mMaxRadiusRate = 1f;//0.85f;
|
||
private boolean mMaxRadiusSet;
|
||
|
||
private boolean mIsRunning;
|
||
private long mLastCreateTime;
|
||
private List<Circle> mCircleList = new ArrayList<Circle>();
|
||
|
||
private Runnable mCreateCircle = new Runnable() {
|
||
@Override
|
||
public void run() {
|
||
if (mIsRunning) {
|
||
newCircle();
|
||
postDelayed(mCreateCircle, mSpeed);
|
||
}
|
||
}
|
||
};
|
||
|
||
private Interpolator mInterpolator = new LinearInterpolator();
|
||
|
||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||
|
||
public WaveView(Context context) {
|
||
super(context);
|
||
}
|
||
|
||
public WaveView(Context context, AttributeSet attrs) {
|
||
super(context, attrs);
|
||
}
|
||
|
||
public void setStyle(Paint.Style style) {
|
||
mPaint.setStyle(style);
|
||
}
|
||
|
||
@Override
|
||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||
if (!mMaxRadiusSet) {
|
||
mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f;
|
||
}
|
||
}
|
||
|
||
public void setMaxRadiusRate(float maxRadiusRate) {
|
||
mMaxRadiusRate = maxRadiusRate;
|
||
}
|
||
|
||
public void setColor(int color) {
|
||
mPaint.setColor(color);
|
||
}
|
||
|
||
/**
|
||
* 开始
|
||
*/
|
||
public void start() {
|
||
if (!mIsRunning) {
|
||
mIsRunning = true;
|
||
mCreateCircle.run();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 缓慢停止
|
||
*/
|
||
public void stop() {
|
||
mIsRunning = false;
|
||
}
|
||
|
||
/**
|
||
* 立即停止
|
||
*/
|
||
public void stopImmediately() {
|
||
mIsRunning = false;
|
||
mCircleList.clear();
|
||
invalidate();
|
||
}
|
||
|
||
protected void onDraw(Canvas canvas) {
|
||
Iterator<Circle> iterator = mCircleList.iterator();
|
||
while (iterator.hasNext()) {
|
||
Circle circle = iterator.next();
|
||
float radius = circle.getCurrentRadius();
|
||
if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {
|
||
mPaint.setAlpha(circle.getAlpha());
|
||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, mPaint);
|
||
} else {
|
||
iterator.remove();
|
||
}
|
||
}
|
||
if (mCircleList.size() > 0) {
|
||
postInvalidateDelayed(10);
|
||
}
|
||
}
|
||
|
||
public void setInitialRadius(float radius) {
|
||
mInitialRadius = radius;
|
||
}
|
||
|
||
public void setDuration(long duration) {
|
||
mDuration = duration;
|
||
}
|
||
|
||
public void setMaxRadius(float maxRadius) {
|
||
mMaxRadius = maxRadius;
|
||
mMaxRadiusSet = true;
|
||
}
|
||
|
||
public void setSpeed(int speed) {
|
||
mSpeed = speed;
|
||
}
|
||
|
||
private void newCircle() {
|
||
long currentTime = System.currentTimeMillis();
|
||
if (currentTime - mLastCreateTime < mSpeed) {
|
||
return;
|
||
}
|
||
Circle circle = new Circle();
|
||
mCircleList.add(circle);
|
||
invalidate();
|
||
mLastCreateTime = currentTime;
|
||
}
|
||
|
||
private class Circle {
|
||
private long mCreateTime;
|
||
|
||
Circle() {
|
||
mCreateTime = System.currentTimeMillis();
|
||
}
|
||
|
||
int getAlpha() {
|
||
float percent = (getCurrentRadius() - mInitialRadius) / (mMaxRadius - mInitialRadius);
|
||
return (int) ((55 - mInterpolator.getInterpolation(percent) * 46));
|
||
//Log.i("透明度",""+mInterpolator.getInterpolation(percent));
|
||
//return (int) ((255*0.08)*mInterpolator.getInterpolation(percent));
|
||
}
|
||
|
||
float getCurrentRadius() {
|
||
float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
|
||
return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius);
|
||
}
|
||
}
|
||
|
||
public void setInterpolator(Interpolator interpolator) {
|
||
mInterpolator = interpolator;
|
||
if (mInterpolator == null) {
|
||
mInterpolator = new LinearInterpolator();
|
||
}
|
||
}
|
||
|
||
/*private Context mContext;
|
||
private int centerRadius;
|
||
private int maxRadius;
|
||
private int waveWidth;
|
||
private long waveIntervalTime = 500;
|
||
private long waveDuration = 1500;
|
||
private boolean running = false;
|
||
private List<Wave> waveList = new ArrayList<>();
|
||
private Paint paint = new Paint();
|
||
private int centerColor;
|
||
|
||
public WaveView(Context context) {
|
||
this(context,null);
|
||
}
|
||
|
||
public WaveView(Context context, @Nullable AttributeSet attrs) {
|
||
this(context, attrs,0);
|
||
}
|
||
|
||
public WaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||
super(context, attrs, defStyleAttr);
|
||
mContext = context;
|
||
|
||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WaveView,defStyleAttr,0);
|
||
centerColor = typedArray.getColor(
|
||
R.styleable.WaveView_center_color,
|
||
ContextCompat.getColor(context, R.color.mainTextColor)
|
||
);
|
||
centerRadius = (int) typedArray.getDimension(R.styleable.WaveView_center_radius, 4);
|
||
maxRadius = (int) typedArray.getDimension(R.styleable.WaveView_max_radius, 14f);
|
||
waveWidth = (int) typedArray.getDimension(R.styleable.WaveView_wave_width, 1.0f);
|
||
waveIntervalTime = typedArray.getInt(R.styleable.WaveView_wave_interval_time, 500);
|
||
waveDuration = typedArray.getInt(R.styleable.WaveView_wave_duration, 1500);
|
||
paint.setColor(centerColor);
|
||
typedArray.recycle();
|
||
}
|
||
|
||
public void setWaveStart(boolean waveStart) {
|
||
if (waveStart) {
|
||
if (!running) {
|
||
running = true;
|
||
waveList.add(new Wave());
|
||
}
|
||
} else {
|
||
running = false;
|
||
for (Wave wave: waveList) {
|
||
wave.cancelAnimation();
|
||
}
|
||
}
|
||
}
|
||
|
||
@Override
|
||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||
int radius = (Math.min(w,h)/2);
|
||
if (radius < maxRadius) {
|
||
maxRadius = radius;
|
||
}
|
||
|
||
}
|
||
|
||
@Override
|
||
protected void onDraw(Canvas canvas) {
|
||
super.onDraw(canvas);
|
||
for (Wave wave: waveList) {
|
||
paint.setAlpha(wave.getAlpha());
|
||
paint.setStrokeWidth(waveWidth);
|
||
paint.setStyle(Paint.Style.STROKE);
|
||
canvas.drawCircle(getWidth() >> 1, (getHeight() >> 1), wave.getCurrentRadius(), paint);
|
||
}
|
||
if (waveList.size() > 0) {
|
||
paint.setAlpha(255);
|
||
paint.setStyle(Paint.Style.FILL);
|
||
canvas.drawCircle(getWidth() >> 1, getHeight() >> 1, centerRadius, paint);
|
||
}
|
||
}
|
||
|
||
public class Wave {
|
||
private boolean hasCreateNewWave = false;
|
||
private ValueAnimator createWaveAnimation = ObjectAnimator.ofFloat(this, "percent", 0f, 1.0f);
|
||
private Float percent =0f;
|
||
|
||
@SuppressLint("ObjectAnimatorBinding")
|
||
public void setPercent(Float percent) {
|
||
|
||
this.percent = percent;
|
||
if (running && percent >= waveIntervalTime / waveDuration && !hasCreateNewWave) {
|
||
Wave wave = new Wave();
|
||
wave.createWaveAnimation.setInterpolator(new LinearInterpolator());
|
||
wave.createWaveAnimation.setDuration(waveDuration);
|
||
wave.createWaveAnimation.start();
|
||
wave.createWaveAnimation.addListener(new Animator.AnimatorListener() {
|
||
@Override
|
||
public void onAnimationStart(Animator animation) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onAnimationEnd(Animator animation) {
|
||
if (running) {
|
||
waveList.remove(Wave.this);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onAnimationCancel(Animator animation) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onAnimationRepeat(Animator animation) {
|
||
|
||
}
|
||
});
|
||
waveList.add(wave);
|
||
hasCreateNewWave = true;
|
||
}
|
||
invalidate();
|
||
}
|
||
|
||
public Float getPercent() {
|
||
return percent;
|
||
}
|
||
|
||
public void cancelAnimation() {
|
||
createWaveAnimation.cancel();
|
||
}
|
||
|
||
public int getAlpha() {
|
||
return (int) (255 * (1 - percent));
|
||
}
|
||
|
||
public float getCurrentRadius() {
|
||
return centerRadius + percent * (maxRadius - centerRadius);
|
||
}
|
||
}*/
|
||
|
||
}
|