人生只是一种体验,不必用来演绎完美。
效果图
View源码
java
package com.android.circlescalebar.view;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import androidx.annotation.NonNull;
import com.android.circlescalebar.utils.DensityUtils;
import java.util.ArrayList;
import java.util.List;
public final class WaveView extends View {
private static final String TAG = "WaveView";
private int centerColor = Color.GREEN;
private int centerRadius = DensityUtils.dp2px(1.0F);
private int maxRadius = DensityUtils.dp2px(105.0F);
private int waveIntervalTime= 500;
private int waveDuration = 1500;
private boolean running;
private List<Wave> waveList = new ArrayList();;
private int waveWidth = DensityUtils.dp2px(1.0F);
private Paint paint = new Paint();
public WaveView(Context context) {
super(context);
}
public WaveView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setWaveStart(boolean waveStart) {
if (waveStart) {
if (!running) {
running = true;
waveList.add(new Wave());
}
} else {
running = false;
for (Wave wave : waveList) {
wave.cancelAnimation();
}
}
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
int radius = (int)((float)Math.min(w, h) / 2.0F);
if (radius <maxRadius) {
maxRadius = radius;
}
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(centerColor);
for (Wave wave : waveList) {
paint.setAlpha(wave.getAlpha());
paint.setStrokeWidth((float)this.waveWidth);
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle((float)(this.getWidth() / 2), (float)(this.getHeight() / 2), wave.getCurrentRadius(),paint);
}
if (this.waveList.size() > 0) {
paint.setAlpha(255);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle((float)(this.getWidth() / 2), (float)(this.getHeight() / 2), (float)this.centerRadius,paint);
}
}
public final class Wave {
public boolean hasCreateNewWave;
public final ValueAnimator createWaveAnimation;
public float percent;
// public final float getPercent() {
// return percent;
// }
//
// public final void setPercent(float value) {
//
// Log.d(TAG, "Wave: percent" + value);
// percent = value;
// if (running && value >= (float)waveIntervalTime / (float)waveDuration && !this.hasCreateNewWave) {
// waveList.add(new Wave());
// hasCreateNewWave = true;
// }
// invalidate();
// }
public void cancelAnimation() {
createWaveAnimation.cancel();
}
public int getAlpha() {
return (int)((float)255 * ((float)1 - percent));
}
public float getCurrentRadius() {
return (float)centerRadius +percent * (float)(maxRadius - centerRadius);
}
public Wave() {
// createWaveAnimation = ObjectAnimator.ofFloat(this, "percent", 0F, 1F);
createWaveAnimation = ObjectAnimator.ofFloat(this, "alpha", 0F, 1F);
createWaveAnimation.setInterpolator(new LinearInterpolator());
createWaveAnimation.setDuration(waveDuration);
createWaveAnimation.start();
createWaveAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(@NonNull ValueAnimator valueAnimator) {
float animatedValue = (float) valueAnimator.getAnimatedValue();
percent = animatedValue;
if (running && animatedValue >= (float)waveIntervalTime / (float)waveDuration && !hasCreateNewWave) {
waveList.add(new Wave());
hasCreateNewWave = true;
}
invalidate();
}
});
createWaveAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
waveList.remove(this);
}
});
}
}
}
工具类
java
package com.android.circlescalebar.utils;
import android.content.res.Resources;
public class DensityUtils {
public float density;
public DensityUtils() {
density = Resources.getSystem().getDisplayMetrics().density;
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
* @param dpValue 虚拟像素
* @return 像素
*/
public static int dp2px(float dpValue) {
return (int) (0.5f + dpValue * Resources.getSystem().getDisplayMetrics().density);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
* @param pxValue 像素
* @return 虚拟像素
*/
public static float px2dp(int pxValue) {
return (pxValue / Resources.getSystem().getDisplayMetrics().density);
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
* @param dpValue 虚拟像素
* @return 像素
*/
public int dip2px(float dpValue) {
return (int) (0.5f + dpValue * density);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
* @param pxValue 像素
* @return 虚拟像素
*/
public float px2dip(int pxValue) {
return (pxValue / density);
}
}
调用实现
java
waveView.setWaveStart(true);
布局
java
<com.android.circlescalebar.view.WaveView
android:id="@+id/waveView"
android:layout_width="215dp"
android:layout_height="215dp"
android:layout_gravity="center"/>