Android案例手册 - 定位点圆形水波纹和椭圆水波纹

往期文章分享
  • 点击跳转=>《导航贴》- Unity手册,系统实战学习
  • 点击跳转=>《导航贴》- Android手册,重温移动开发

本文约18千字,新手阅读需要18分钟,复习需要6分钟收藏随时查阅不再迷路

👉关于作者

众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣 !!!
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎私我,交流群让学习不再孤单

在这里插入图片描述

👉前提

这是小空坚持写的Android新手向系列,欢迎品尝。

大佬(√)

新手(√√√)

👉实践过程

先看效果图

定位点圆形水波纹和椭圆水波纹.gif

在相关需求中需要定位医学听诊点,给予用户一个提示反馈。所以封装了一个View。

分为圆形效果和椭圆形效果,并且Java版本和Kotlin版本都有。

如图中,我们可以看出,水波纹一点点扩张且越远越淡,那么我们就知道怎么做了。

  1. 声明一个圆类,随着时间的推移这个圆的透明度和半径进行变化
  2. 声明一个圆类数组,然后隔一段时间创建一个圆类添加进数组
  3. 在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"><!--人物背景图--><ImageViewandroid:layout_width="600dp"android:layout_height="900dp"android:src="@drawable/weizhi_bg" /><cn.appstudy.customView.WaveViewJavaandroid:id="@+id/testWaveViewJava"android:layout_width="80dp"android:layout_height="80dp"android:layout_marginStart="150dp"android:layout_marginTop="420dp" /><cn.appstudy.customView.WaveOvalViewJavaandroid: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() {@Overridepublic 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;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {if (!mMaxRadiusSet) {mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f;}}@Overrideprotected 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? = nullvar 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 = maxRadiusmMaxRadiusSet = true}/*** 波纹创建速度* @param speed*/fun setSpeed(speed: Int) {mSpeed = speed}/*** 插值器,达到不同的效果* @param interpolator*/fun setInterpolator(interpolator: Interpolator) {mInterpolator = interpolatorif (mInterpolator == null) {mInterpolator = LinearInterpolator()}}/*** 提供给外界 设置画笔风格* @param style*/fun setPaintStyle(style: Paint.Style?) {mPaint!!.style = style}/*** 提供给外界开来是整个过程*/fun start() {if (!mIsRunning) {mIsRunning = truemCreateCircle.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() {@Overridepublic 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;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {if (!mMaxRadiusSet) {mMaxRadius = Math.min(w, h) * mMaxRadiusRate / 2.0f;}}@Overrideprotected 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? = nullvar 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 = maxRadiusmMaxRadiusSet = true}/*** 波纹创建速度* @param speed*/fun setSpeed(speed: Int) {mSpeed = speed}/*** 插值器,达到不同的效果* @param interpolator*/fun setInterpolator(interpolator: Interpolator) {mInterpolator = interpolatorif (mInterpolator == null) {mInterpolator = LinearInterpolator()}}/*** 提供给外界 设置画笔风格** @param style*/fun setPaintStyle(style: Paint.Style?) {mPaint!!.style = style}/*** 提供给外界开来是整个过程*/fun start() {if (!mIsRunning) {mIsRunning = truemCreateCircle.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()}}
}

👉其他

📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。

温馨提示点击下方卡片获取更多意想不到的资源。
空名先生

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/45520.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

聊聊Android5.0中的水波纹效果

水波纹效果已经不是什么稀罕的东西了&#xff0c;用过5.0新控件的小伙伴都知道这个效果&#xff0c;可是如果使用一个TextView或者Button或者其它普通控件的话&#xff0c;你是否知道如何给它设置水波纹效果呢&#xff1f;OK&#xff0c;我们今天就来看看这个水波纹效果的实现。…

Android开发中的水波纹效果实现

编写不易&#xff0c;如有转载&#xff0c;请声明出处&#xff1a;http://blog.csdn.net/zxc514257857/article/details/73200900 前言 android中的水波纹效果是5.0以后即API Level 21以后出现的&#xff0c;因此minSdkVersion必须设置在21及以上才可以使用此效果 Demo效果展示…

Android点击水波纹扩散效果整理(附带一个自定义的水波纹效果控件)

很久很久没有写博客了&#xff0c;说来也有点惭愧。正好最近整理自己的项目工程目录&#xff0c;看到一些值得分享的控件&#xff0c;准备在之后的几篇博客中准备把它们陆续搬运上来。 这篇博客准备整理一下Android Material Design自带的点击水波纹扩散的效果。话不多说&#…

android 按钮水波纹效果【背景色】

两种方式实现&#xff1a; 第一种&#xff1a;Material自带水波纹 通过如下代码设置波纹的背景&#xff1a; android:background"?android:attr/selectableItemBackground"波纹有边界【一般这种好看点&#xff0c;大多数也都是这种】 android:foreground"?…

Android 水波纹扩散效果

项目地址下载&#xff1a;https://github.com/LiuJunb/RippleImageView 1.效果图&#xff1a; 2.使用方法&#xff1a; 在xml里使用RippleImageView自定义控件&#xff1a; xmlns:app"http://schemas.android.com/apk/res-auto"<com.army.rippleimage.RippleIma…

Android 自定义view实现水波纹效果

http://blog.csdn.net/tianjian4592/article/details/44222565 在实际的开发中&#xff0c;很多时候还会遇到相对比较复杂的需求&#xff0c;比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果&#xff0c;兴致高昂的来找你&#xff0c;看了之后目的很明确&#xff0c;当然就是希望…

Android点击Button水波纹效果

先上图&#xff0c;看看接下来我要向大家介绍的是个什么东西&#xff0c;如下图&#xff1a; 接下来要介绍的就是如何实现上述图中的波纹效果&#xff0c;这种效果如果大家没有体验过的话&#xff0c;可以看看百度手机卫士或者360手机卫士&#xff0c;里面的按钮点击效果都是…

unity 实现水的波纹效果

之前的实现过这个效果&#xff0c;可惜没有记笔记&#xff0c;所以现在有点遗忘&#xff0c;连多个波纹一起在水面上实现的效果都忘记了&#xff0c;所以&#xff0c;查看了下之前实现的代码&#xff0c;现在再记一下笔记。 基础的波纹效果 要实现波纹&#xff0c;首先要知道…

Android水波纹效果

日常的Android开发中可能大家都见过类似这种水波纹展开的效果&#xff0c;比如加载一张图片的时候使用水波纹加载&#xff0c;其实这种实现非常简单。因为Google已经为我们提供了一个非常方便地工具类 ViewAnimationUtils 它的实现非常简单&#xff0c;就这个类&#xff0c;其…

自定义view实现水波纹效果

我正在参加 CSDN 2015博客之星评选 感恩分享活动&#xff0c;如果觉得文章还不错&#xff0c;请投个票鼓励下吧&#xff1a;http://vote.blog.csdn.net/blogstar2015/candidate?usernametianjian4592 在实际的开发中&#xff0c;很多时候还会遇到相对比较复杂的需求&#xf…

Android L中水波纹点击效果的实现

博主参加了2014 CSDN博客之星评选&#xff0c;帮我投一票吧。 点击给我投票 前言 前段时间android L&#xff08;android 5.0&#xff09;出来了&#xff0c;界面上做了一些改动&#xff0c;主要是添加了若干动画和一些新的控件&#xff0c;相信大家对view的点击效果-水波纹很…

科技云报道:垂直大模型竞争,能突破数据“卡点”吗?

科技云报道原创。 AI大模型火遍全球&#xff0c;中国产业也激发了对人工智能应用的新热情。 随着各大厂商参与竞逐&#xff0c;市场正在分化为通用与垂直两大路径&#xff0c;两者在参数级别、应用场景、商业模式等方面差异已逐步显现。 企业涌入垂直大模型赛道 通用AI大模型…

【人工智能】论未来人工智能的大模型生态:重塑技术前景与应用

目录 未来人工智能大模型生态:重塑技术前景与应用 引言 OpenAI 的 AGI 愿景

创造之境:Stable Diffusion + chatGPT下的自动绘图探索

什么是Stable Diffusion Stable Diffusion 是在2022年发布的深度学习文本到图像生成模型。它主要用于根据文字的描述生成详细图像&#xff0c;尽管它也可以应用于其他任务&#xff0c;如内插绘制、外插绘制&#xff0c;以及在提示词&#xff08;英语&#xff09;指导下生成图生…

工具 | ChatPDF:与PDF对话!

工具 | ChatPDF&#xff1a;与PDF对话&#xff01; 本文首发微信公众号&#xff1a;全副武装的大师兄 ChatPDF是什么&#xff1f; 它是一个在不到一周时间里&#xff0c;就让10万份PDF学会了聊天的应用&#xff01;无需注册&#xff0c;登录&#xff0c;通过上传PDF文件到Ch…

微信公众号 接口配置

1、登录微信公众平台-->设置与开发-->基本配置页面&#xff0c;打开服务器配置 2、在网站后台添加两个接口get请求验证和post请求消息转发&#xff0c;url为上图填写的url&#xff0c; RestController RequestMapping("/officialAccount/") public class Offic…

亚马逊评论和销量的关系都有哪些呢?

评论和销量的关系非常密切。当然不是评论越多越好&#xff0c;更合理的评论对产品的关键词排名帮助更大。就连亚马逊也会推荐一些资源&#xff0c;所以推荐和曝光越多&#xff0c;销量也会增加越多。这也是为什么卖家都在努力增加Review数量&#xff0c;甚至花钱找人做评测还免…

亚马逊评论的类型有哪些?都该怎么操作呢?

亚马逊评论对于亚马逊卖家店铺来说很重要的&#xff0c;评论又多又好的产品自然更受欢迎&#xff0c;但是评论肯定不只一种&#xff0c;那么亚马逊评论的类型有哪些&#xff1f;都该怎么操作呢&#xff1f; 亚马逊评论分为以下几种&#xff1a; 1、直评 直评是买家可以不用购…

视频会议解决方案-最新全套文件

视频会议解决方案-最新全套文件 一、建设背景二、建设思路业务挑战 三、建设方案四、获取 - 视频会议全套最新解决方案合集 一、建设背景 随着中国经济的迅速发展&#xff0c;很多企业的发展也进入快车道&#xff0c;分支机构越来越多&#xff0c;形成了遍布全国范围甚至全球范…

微软:明年 7 月之前,所有会议线上举行

By 超神经 内容提要&#xff1a;这场疫情对科技行业带来了重大影响。自 2 月以来&#xff0c;被迫取消或转至线上的科技峰会已经数不胜数。现在&#xff0c;微软已经决定&#xff0c;将明年下半年之前的所有活动转至线上&#xff0c;科技会议或许就此迎来变革&#xff1f; 关键…