Android案例手册 - 定位点圆形水波纹和椭圆水波纹
👉关于作者
众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣!!!
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
欢迎关注公众号【空名先生】获取更多资源和交流!
👉前提
这是小空坚持写的Android新手向系列,欢迎品尝。
新手(√√√)
大佬(√)
👉实践过程
先看效果图
在相关需求中需要定位医学听诊点,给予用户一个提示反馈。所以封装了一个View。
分为圆形效果和椭圆形效果,并且Java版本和Kotlin版本都有。
如图中,我们可以看出,水波纹一点点扩张且越远越淡,那么我们就知道怎么做了。
- 声明一个圆类,随着时间的推移这个圆的透明度和半径进行变化
- 声明一个圆类数组,然后隔一段时间创建一个圆类添加进数组
- 在onDraw中遍历数组绘制出来,判断当前时间距离创建时间大于多少秒就从圆类数组中删除即可。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--人物背景图-->
<ImageView
android:layout_width="600dp"
android:layout_height="900dp"
android:src="@drawable/weizhi_bg" />
<cn.appstudy.customView.WaveViewJava
android:id="@+id/testWaveViewJava"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="150dp"
android:layout_marginTop="420dp" />
<cn.appstudy.customView.WaveOvalViewJava
android:id="@+id/testWaveOvalViewJava"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="260dp"
android:layout_marginTop="520dp" />
</RelativeLayout>
然后代码中找到这个布局View的id,调用start方法即可。
😜WaveView-圆形
如下代码类
创建一个可控变量定为波纹从创建到校时的持续时间,当然这个变量完全可以供外部修改。
创建一个变量控制波纹创建的间隔。
创建圆的相关变量(半径,颜色,画笔等等)。
start()方法为启动方法,开启反复的Runnable,间隔时间就是波纹创建时间,里面写创建圆的逻辑。
创建圆类,将当前时间记录下来保存进去,圆类中提供两个方法,更新的当前时间减去创建时候保存的的“当前时间”,这个插值是越来越大的,那么就可以修改透明度和半径。
之后便是onDraw中遍历圆类的数组,判断当前的时间和圆类中保存的创建时间,大于设定持续时间的值则销毁,否则用画笔在canvas进行绘制。
Java版
/**
* @author akitaka
* @filename WaveViewJava
*/
public class WaveViewJava extends View {
private long mDuration = 2000; // 一个波纹从创建到消失的持续时间
/**
* 插值器属性,可理解为指定动画如何变化的动动;有多种
* LinearInterpolator--画从开始到结束,变化率是线性变化
*/
private Interpolator mInterpolator = new LinearInterpolator();
private float mInitialRadius; // 初始波纹半径
private float mMaxRadius; // 最大波纹半径
private Paint mPaint;
private List<Circle> mCircleList = new ArrayList<>();//当前正在显示的圆集合
private boolean mIsRunning;//绘制线程是否开始
private int mSpeed = 500; // 波纹的创建速度,每500ms创建一个
private long mLastCreateTime; //上一个创建圆的时间
private boolean mMaxRadiusSet; //如果设置了最大半径
private float mMaxRadiusRate = 0.85f; // 如果没有设置mMaxRadius,可mMaxRadius = 最小长度 * mMaxRadiusRate;
public WaveViewJava (Context context) {
super(context);
}
public WaveViewJava (Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿
mPaint.setColor(Color.WHITE);
setPaintStyle(Paint.Style.FILL); //填充式
}
/**
* 波纹半径率
* @param maxRadiusRate
*/
public void setMaxRadiusRate(float maxRadiusRate) {
this.mMaxRadiusRate = maxRadiusRate;
}
/**
* 画笔颜色
* @param color
*/
public void setColor(int color) {
mPaint.setColor(color);
}
/**
* 初始半径
* @param radius
*/
public void setInitialRadius(float radius) {
mInitialRadius = radius;
}
/**
* 设置波纹持续时间
* @param duration
*/
public void setDuration(long duration) {
this.mDuration = duration;
}
/**
* 最大波纹半径
* @param maxRadius
*/
public void setMaxRadius(float maxRadius) {
this.mMaxRadius = maxRadius;
mMaxRadiusSet = true;
}
/**
* 波纹创建速度
* @param speed
*/
public void setSpeed(int speed) {
mSpeed = speed;
}
/**
* 插值器,达到不同的效果
* @param interpolator
*/
public void setInterpolator(Interpolator interpolator) {
mInterpolator = interpolator;
if (mInterpolator == null) {
mInterpolator = new LinearInterpolator();
}
}
/**
* 提供给外界 设置画笔风格
* @param style
*/
public void setPaintStyle(Paint.Style style) {
mPaint.setStyle(style);
}
/**
* 提供给外界开来是整个过程
*/
public void start() {
if (!mIsRunning) {
mIsRunning = true;
mCreateCircle.run(); //开线程
}
}
/**
* 停止
*/
public void stop() {
mIsRunning = false;
}
private Runnable mCreateCircle = new Runnable() {
@Override
public void run() {
if (mIsRunning) {
newCircle();
postDelayed(mCreateCircle, mSpeed); // 每隔mSpeed毫秒创建一个圆
}
}
};
/**
* 创建圆
*/
private void newCircle() {
long currentTime = System.currentTimeMillis();
if (currentTime - mLastCreateTime < mSpeed) {
return;
}
Circle circle = new Circle();
mCircleList.add(circle);
invalidate(); //重新调用onDraw绘制
mLastCreateTime = currentTime;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (!mMaxRadiusSet) {
mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f;
}
}
@Override
protected void onDraw(Canvas canvas) {
Iterator<Circle> iterator = mCircleList.iterator(); //得带期遍历
while (iterator.hasNext()) { //是否=还有元素
Circle circle = iterator.next();//拿到下一个
if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {
mPaint.setAlpha(circle.getAlpha()); //设置透明度
canvas.drawCircle(getWidth() / 2, getHeight() / 2, circle.getCurrentRadius(), mPaint); //设置半径
} else { //如果创建的时间大于最大 则移除
iterator.remove();
}
}
if (mCircleList.size() > 0) {
postInvalidateDelayed(10); //10毫秒刷新 快速给人错觉是动态的 其实是静态的很多圆
}
}
/**
* 绘制圆的类 getAlpha、getCurrentRadius插值器原因
* 你可以在外部设置不同的插值器器,来实现波纹的不同动态效果;详情请学习插值器;
*/
private class Circle {
private long mCreateTime; //当前添加圆时间
public Circle() {
this.mCreateTime = System.currentTimeMillis();
}
/**
* 获得透明度 ↓0(消失)
* getInterpolation传值越大,返回越大 因为是LinearInterpolator 传值返回一致
* @return
*/
public int getAlpha() {
//当前时间处于总时间的百分比 当前时间/圆创建-消失总时间
float percent = (float) ((System.currentTimeMillis() - mCreateTime) * 1.0 / mDuration);
return (int) ((1.0f - mInterpolator.getInterpolation(percent)) * 255);
}
/**
* 获得当前的半径
*/
public float getCurrentRadius() {
float percent = (float) ((System.currentTimeMillis() - mCreateTime) * 1.0 / mDuration);
//最小半径+当前扩大百分比半径
return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius);
}
}
}
Kotlin版
/**
* Created by akitaka on 2022-06-22.
* @author akitaka
* @filename WaveViewKotlin
* @describe
* @email 960576866@qq.com
*/
class WaveViewKotlin : View {
constructor(context: Context?) : this(context, null)
constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
var mDuration: Long = 2000 // 一个波纹从创建到消失的持续时间
/**
* 插值器属性,可理解为指定动画如何变化的动动;有多种
* LinearInterpolator--画从开始到结束,变化率是线性变化
*/
var mInterpolator: Interpolator = LinearInterpolator()
var mInitialRadius = 0f// 初始波纹半径
var mMaxRadius = 0f// 最大波纹半径
var mPaint: Paint? = null
var mCircleList: MutableList<Circle> = ArrayList() //当前正在显示的圆集合
var mIsRunning = false//绘制线程是否开始
var mSpeed = 500 // 波纹的创建速度,每500ms创建一个
var mLastCreateTime: Long = 0//上一个创建圆的时间
var mMaxRadiusSet = false//如果设置了最大半径
var mMaxRadiusRate = 0.85f // 如果没有设置mMaxRadius,可mMaxRadius = 最小长度 * mMaxRadiusRate;
init {
mPaint = Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿
mPaint!!.color = Color.GREEN;
setPaintStyle(Paint.Style.FILL); //填充式
}
/**
* 波纹半径率
* @param maxRadiusRate
*/
fun setMaxRadiusRate(maxRadiusRate: Float) {
mMaxRadiusRate = maxRadiusRate
}
/**
* 画笔颜色
* @param color
*/
fun setColor(color: Int) {
mPaint!!.color = color
}
/**
* 初始半径
* @param radius
*/
fun setInitialRadius(radius: Float) {
mInitialRadius = radius
}
/**
* 设置波纹持续时间
* @param duration
*/
fun setDuration(duration: Long) {
mDuration = duration
}
/**
* 最大波纹半径
* @param maxRadius
*/
fun setMaxRadius(maxRadius: Float) {
mMaxRadius = maxRadius
mMaxRadiusSet = true
}
/**
* 波纹创建速度
* @param speed
*/
fun setSpeed(speed: Int) {
mSpeed = speed
}
/**
* 插值器,达到不同的效果
* @param interpolator
*/
fun setInterpolator(interpolator: Interpolator) {
mInterpolator = interpolator
if (mInterpolator == null) {
mInterpolator = LinearInterpolator()
}
}
/**
* 提供给外界 设置画笔风格
* @param style
*/
fun setPaintStyle(style: Paint.Style?) {
mPaint!!.style = style
}
/**
* 提供给外界开来是整个过程
*/
fun start() {
if (!mIsRunning) {
mIsRunning = true
mCreateCircle.run() //开线程
}
}
/**
* 停止
*/
fun stop() {
mIsRunning = false
}
private val mCreateCircle: Runnable = object : Runnable {
override fun run() {
if (mIsRunning) {
newCircle()
postDelayed(this, mSpeed.toLong()) // 每隔mSpeed毫秒创建一个圆
}
}
}
/**
* 创建圆
*/
private fun newCircle() {
val currentTime = System.currentTimeMillis()
if (currentTime - mLastCreateTime < mSpeed) {
return
}
val circle = Circle()
mCircleList.add(circle)
invalidate() //重新调用onDraw绘制
mLastCreateTime = currentTime
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
if (!mMaxRadiusSet) {
mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f
}
}
override fun onDraw(canvas: Canvas) {
val iterator = mCircleList.iterator() //得带期遍历
while (iterator.hasNext()) { //是否=还有元素
val circle = iterator.next() //拿到下一个
if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {
mPaint!!.alpha = circle.getAlpha() //设置透明度
canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), circle.getCurrentRadius(), mPaint!!) //设置半径
} else { //如果创建的时间大于最大 则移除
iterator.remove()
}
}
if (mCircleList.size > 0) {
postInvalidateDelayed(10) //10毫秒刷新 快速给人错觉是动态的 其实是静态的很多圆
}
}
/**
* 绘制圆的类 getAlpha、getCurrentRadius插值器原因
* 你可以在外部设置不同的插值器器,来实现波纹的不同动态效果;详情请学习插值器;
* kotlin要想内部类访问外部类的成员变量 需要inner修饰
*/
inner class Circle {
val mCreateTime: Long //当前添加圆时间
/**
* 获得透明度 ↓0(消失)
* getInterpolation传值越大,返回越大 因为是LinearInterpolator 传值返回一致
*
* @return
*/
fun getAlpha(): Int {
//当前时间处于总时间的百分比 当前时间/圆创建-消失总时间
val percent: Float = ((System.currentTimeMillis() - mCreateTime) * 1.0 / mDuration).toFloat()
return ((1.0f - mInterpolator.getInterpolation(percent)) * 255).toInt()
}
/**
* 获得当前的半径
*/
fun getCurrentRadius(): Float {
val percent: Float = ((System.currentTimeMillis() - mCreateTime) * 1.0 / mDuration).toFloat()
//最小半径+当前扩大百分比半径
return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius)
}
init {
mCreateTime = System.currentTimeMillis()
}
}
}
😜WaveOvalView-椭圆
椭圆的绘制和圆的绘制仅仅差在onDraw中,其他的都一样。onDraw使用canvas.drawOval即可。
Java版
/**
*
* @author akitaka
* @filename WaveOvalViewJava
* @describe 椭圆形的水波纹,而且椭圆的扁平方向也需要控制;;后期可考虑封装,继承WaveViewJava或者整体
* @email 960576866@qq.com
*/
public class WaveOvalViewJava extends View {
private long mDuration = 2000; // 一个波纹从创建到消失的持续时间
/**
* 插值器属性,可理解为指定动画如何变化的动动;有多种
* LinearInterpolator--画从开始到结束,变化率是线性变化
*/
private Interpolator mInterpolator = new LinearInterpolator();
private float mInitialRadius; // 初始波纹半径
private float mMaxRadius; // 最大波纹半径
private Paint mPaint;
private List<Circle> mCircleList = new ArrayList<>();//当前正在显示的圆集合
private boolean mIsRunning;//绘制线程是否开始
private int mSpeed = 500; // 波纹的创建速度,每500ms创建一个
private long mLastCreateTime; //上一个创建圆的时间
private boolean mMaxRadiusSet; //如果设置了最大半径
private float mMaxRadiusRate = 0.85f; // 如果没有设置mMaxRadius,可mMaxRadius = 最小长度 * mMaxRadiusRate;
public WaveOvalViewJava(Context context) {
super(context);
}
public WaveOvalViewJava (Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿
setPaintStyle(Paint.Style.FILL); //填充式
}
/**
* 波纹半径率
* @param maxRadiusRate
*/
public void setMaxRadiusRate(float maxRadiusRate) {
this.mMaxRadiusRate = maxRadiusRate;
}
/**
* 画笔颜色
* @param color
*/
public void setColor(int color) {
mPaint.setColor(color);
}
/**
* 初始半径
* @param radius
*/
public void setInitialRadius(float radius) {
mInitialRadius = radius;
}
/**
* 设置波纹持续时间
* @param duration
*/
public void setDuration(long duration) {
this.mDuration = duration;
}
/**
* 最大波纹半径
* @param maxRadius
*/
public void setMaxRadius(float maxRadius) {
this.mMaxRadius = maxRadius;
mMaxRadiusSet = true;
}
/**
* 波纹创建速度
* @param speed
*/
public void setSpeed(int speed) {
mSpeed = speed;
}
/**
* 插值器,达到不同的效果
* @param interpolator
*/
public void setInterpolator(Interpolator interpolator) {
mInterpolator = interpolator;
if (mInterpolator == null) {
mInterpolator = new LinearInterpolator();
}
}
/**
* 提供给外界 设置画笔风格
* @param style
*/
public void setPaintStyle(Paint.Style style) {
mPaint.setStyle(style);
}
/**
* 提供给外界开来是整个过程
*/
public void start() {
if (!mIsRunning) {
mIsRunning = true;
mCreateCircle.run(); //开线程
}
}
/**
* 停止
*/
public void stop() {
mIsRunning = false;
}
private Runnable mCreateCircle = new Runnable() {
@Override
public void run() {
if (mIsRunning) {
newCircle();
postDelayed(mCreateCircle, mSpeed); // 每隔mSpeed毫秒创建一个圆
}
}
};
/**
* 创建圆
*/
private void newCircle() {
long currentTime = System.currentTimeMillis();
if (currentTime - mLastCreateTime < mSpeed) {
return;
}
Circle circle = new Circle();
mCircleList.add(circle);
invalidate(); //重新调用onDraw绘制
mLastCreateTime = currentTime;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (!mMaxRadiusSet) {
mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f;
}
}
@Override
protected void onDraw(Canvas canvas) {
Iterator<Circle> iterator = mCircleList.iterator(); //得带期遍历
while (iterator.hasNext()) { //是否=还有元素
Circle circle = iterator.next();//拿到下一个
if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {
mPaint.setAlpha(circle.getAlpha()); //设置透明度
// canvas.drawCircle(getWidth() / 2, getHeight() / 2, circle.getCurrentRadius(), mPaint); //设置半径来控制为椭圆
RectF ovalRect = new RectF();
//椭圆的绘制封装 需要更精细的考虑, left,top小于 right,bottom;;
ovalRect.left = getWidth() / 2 - circle.getCurrentRadius();
ovalRect.top = getWidth() / 2 - 1.5f * circle.getCurrentRadius();
ovalRect.right = getWidth() / 2 + circle.getCurrentRadius();
ovalRect.bottom = getWidth() / 2 + 1.5f * circle.getCurrentRadius();
canvas.drawOval(ovalRect, mPaint);
//需要API 21
// canvas.drawOval(circle.getCurrentRadius(),circle.getCurrentRadius()-10,circle.getCurrentRadius(),circle.getCurrentRadius()-10,mPaint);
} else { //如果创建的时间大于最大 则移除
iterator.remove();
}
}
if (mCircleList.size() > 0) {
postInvalidateDelayed(10); //10毫秒刷新 快速给人错觉是动态的 其实是静态的很多圆
}
}
/**
* 绘制圆的类 getAlpha、getCurrentRadius插值器原因
* 你可以在外部设置不同的插值器器,来实现波纹的不同动态效果;详情请学习插值器;
*/
private class Circle {
private long mCreateTime; //当前添加圆时间
public Circle() {
this.mCreateTime = System.currentTimeMillis();
}
/**
* 获得透明度 ↓0(消失)
* getInterpolation传值越大,返回越大 因为是LinearInterpolator 传值返回一致
* @return
*/
public int getAlpha() {
//当前时间处于总时间的百分比 当前时间/圆创建-消失总时间
float percent = (float) ((System.currentTimeMillis() - mCreateTime) * 1.0 / mDuration);
return (int) ((1.0f - mInterpolator.getInterpolation(percent)) * 255);
}
/**
* 获得当前的半径
*/
public float getCurrentRadius() {
float percent = (float) ((System.currentTimeMillis() - mCreateTime) * 1.0 / mDuration);
//最小半径+当前扩大百分比半径
return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius);
}
}
}
Kotlin版
/**
* Created by akitaka on 2022-06-23.
* @author akitaka
* @filename WaveOvalViewKotlin
* @describe
* @email 960576866@qq.com
*/
class WaveOvalViewKotlin : View {
constructor(context: Context?) : this(context, null)
constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
var mDuration: Long = 2000 // 一个波纹从创建到消失的持续时间
/**
* 插值器属性,可理解为指定动画如何变化的动动;有多种
* LinearInterpolator--画从开始到结束,变化率是线性变化
*/
var mInterpolator: Interpolator = LinearInterpolator()
var mInitialRadius = 0f// 初始波纹半径
var mMaxRadius = 0f// 最大波纹半径
var mPaint: Paint? = null
var mCircleList: MutableList<Circle> = ArrayList() //当前正在显示的圆集合
var mIsRunning = false//绘制线程是否开始
var mSpeed = 500 // 波纹的创建速度,每500ms创建一个
var mLastCreateTime: Long = 0//上一个创建圆的时间
var mMaxRadiusSet = false//如果设置了最大半径
var mMaxRadiusRate = 0.85f // 如果没有设置mMaxRadius,可mMaxRadius = 最小长度 * mMaxRadiusRate;
init {
mPaint = Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿
mPaint!!.color = Color.GREEN;
setPaintStyle(Paint.Style.FILL); //填充式
}
/**
* 波纹半径率
* @param maxRadiusRate
*/
fun setMaxRadiusRate(maxRadiusRate: Float) {
mMaxRadiusRate = maxRadiusRate
}
/**
* 画笔颜色
* @param color
*/
fun setColor(color: Int) {
mPaint!!.color = color
}
/**
* 初始半径
* @param radius
*/
fun setInitialRadius(radius: Float) {
mInitialRadius = radius
}
/**
* 设置波纹持续时间
* @param duration
*/
fun setDuration(duration: Long) {
mDuration = duration
}
/**
* 最大波纹半径
* @param maxRadius
*/
fun setMaxRadius(maxRadius: Float) {
mMaxRadius = maxRadius
mMaxRadiusSet = true
}
/**
* 波纹创建速度
* @param speed
*/
fun setSpeed(speed: Int) {
mSpeed = speed
}
/**
* 插值器,达到不同的效果
* @param interpolator
*/
fun setInterpolator(interpolator: Interpolator) {
mInterpolator = interpolator
if (mInterpolator == null) {
mInterpolator = LinearInterpolator()
}
}
/**
* 提供给外界 设置画笔风格
*
* @param style
*/
fun setPaintStyle(style: Paint.Style?) {
mPaint!!.style = style
}
/**
* 提供给外界开来是整个过程
*/
fun start() {
if (!mIsRunning) {
mIsRunning = true
mCreateCircle.run() //开线程
}
}
/**
* 停止
*/
fun stop() {
mIsRunning = false
}
private val mCreateCircle: Runnable = object : Runnable {
override fun run() {
if (mIsRunning) {
newCircle()
postDelayed(this, mSpeed.toLong()) // 每隔mSpeed毫秒创建一个圆
}
}
}
/**
* 创建圆
*/
private fun newCircle() {
val currentTime = System.currentTimeMillis()
if (currentTime - mLastCreateTime < mSpeed) {
return
}
val circle = Circle()
mCircleList.add(circle)
invalidate() //重新调用onDraw绘制
mLastCreateTime = currentTime
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
if (!mMaxRadiusSet) {
mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f
}
}
override fun onDraw(canvas: Canvas) {
val iterator: MutableIterator<Circle> = mCircleList.iterator() //得遍历
while (iterator.hasNext()) { //是否=还有元素
val circle = iterator.next() //拿到下一个
if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {
mPaint!!.alpha = circle.getAlpha() //设置透明度
// canvas.drawCircle(getWidth() / 2, getHeight() / 2, circle.getCurrentRadius(), mPaint); //设置半径来控制为椭圆
val ovalRect = RectF()
//椭圆的绘制封装 需要更精细的考虑, left,top小于 right,bottom;;
ovalRect.left = width / 2 - circle.getCurrentRadius()
ovalRect.top = width / 2 - 1.5f * circle.getCurrentRadius()
ovalRect.right = width / 2 + circle.getCurrentRadius()
ovalRect.bottom = width / 2 + 1.5f * circle.getCurrentRadius()
canvas.drawOval(ovalRect, mPaint)
//需要API 21
// canvas.drawOval(circle.getCurrentRadius(),circle.getCurrentRadius()-10,circle.getCurrentRadius(),circle.getCurrentRadius()-10,mPaint);
} else { //如果创建的时间大于最大 则移除
iterator.remove()
}
}
if (mCircleList.size > 0) {
postInvalidateDelayed(10) //10毫秒刷新 快速给人错觉是动态的 其实是静态的很多圆
}
}
/**
* 绘制圆的类 getAlpha、getCurrentRadius插值器原因
* 你可以在外部设置不同的插值器器,来实现波纹的不同动态效果;详情请学习插值器;
* kotlin要想内部类访问外部类的成员变量 需要inner修饰
*/
inner class Circle {
val mCreateTime: Long //当前添加圆时间
/**
* 获得透明度 ↓0(消失)
* getInterpolation传值越大,返回越大 因为是LinearInterpolator 传值返回一致
*
* @return
*/
fun getAlpha(): Int {
//当前时间处于总时间的百分比 当前时间/圆创建-消失总时间
val percent: Float = ((System.currentTimeMillis() - mCreateTime) * 1.0 / mDuration).toFloat()
return ((1.0f - mInterpolator.getInterpolation(percent)) * 255).toInt()
}
/**
* 获得当前的半径
*/
fun getCurrentRadius(): Float {
val percent: Float = ((System.currentTimeMillis() - mCreateTime) * 1.0 / mDuration).toFloat()
//最小半径+当前扩大百分比半径
return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius)
}
init {
mCreateTime = System.currentTimeMillis()
}
}
}
📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:芝麻粒儿 的个人主页 - 专栏 - 掘金 (juejin.cn)
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。
- 点赞
- 收藏
- 关注作者
评论(0)