android水波圆圈动画,Android支付宝咻咻水波纹效果的实现
概述
最近看到支付宝咻咻的页面就想模仿一下,话不多说,先看效果图。(录制的有点渣)
GIF.gif
先说说这个效果:
1.点击中间图标开始搜索附近的人。
2.开始搜索后水波纹一圈圈的加速向外扩张。
3.搜索到人之后以一个圆圈显示在水波纹上。
技术点:
1.要熟悉canvas,paint,,其中canvas的画圆,画图片(主要用于中间圆形图片的绘制,小圆圈也要用圆形图片来绘制的,由于偷懒就用蓝圆点了)。
2.水波纹一圈圈的向外扩张,圆圈扩张的半径计算是利用ValueAnimator来获取的,其中加速扩张还是减速扩张等等这些效果通过Interpolator插值器来实现的,当然也可以自己自定义Interpolator来实现想要的效果。
3.小圆圈是通过自定义viewgroup的onlayout来定位的,这里实现的定位是通过随机的角度加上随机的半径来算出小圆圈所在的坐标,当然你也可以通过距离的远近或者其他来算出小圆圈的坐标。
水波纹效果WaveView
需要水波不停的一波波的向外扩张,所以需要不停的创建水波纹,这里利用了Runnable加上postDelayed来不停的创建水波纹。
private Runnable mWaveRunable = new Runnable() {
@Override
public void run() {
if (mIsRuning) {
newWaveAnimator();
invalidate();
postDelayed(mWaveRunable, mSpeed);
}
}
};
private ValueAnimator newWaveAnimator() {
final ValueAnimator mWaveAnimator = new ValueAnimator();
mWaveAnimator.setFloatValues(mMiniRadius, mMaxRadius);
mWaveAnimator.setDuration(mWaveDuration);
mWaveAnimator.setRepeatCount(0);
mWaveAnimator.setInterpolator(mInterpolator);
mWaveAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// (Float) animation.getAnimatedValue();
}
});
mAnimatorList.add(mWaveAnimator);
mWaveAnimator.start();
return mWaveAnimator;
}
绘制的时候遍历所有的水波纹,然后根据AnimatedValue来获取透明度和半径,当半径达到最大半径的时候删除水波纹,最后就是绘制中间的图标,然后每隔10ms的重新绘制水波纹(貌似10ms是属性动画的帧间隔时间)
@Override
protected void onDraw(Canvas canvas){
Iterator iterator = mAnimatorList.iterator();
while (iterator.hasNext()){
ValueAnimator valueAnimator = iterator.next();
Log.e("AnimatedValue",(float)valueAnimator.getAnimatedValue() + "mMaxRadius:" + mMaxRadius);
if (!valueAnimator.getAnimatedValue().equals(mMaxRadius)){
//设置透明度
mWavePaint.setAlpha(getAlpha((Float) valueAnimator.getAnimatedValue()));
//画水波纹
canvas.drawCircle(getMeasuredWidth() / 2,getMeasuredHeight() / 2, (Float) valueAnimator.getAnimatedValue(),mWavePaint);
}else{
valueAnimator.cancel();
iterator.remove();
}
}
//绘制中间图标
drawCenterBitmap(canvas);
if (mAnimatorList.size() > 0){
postInvalidateDelayed(10);
}
}
点击中间图标开启水波纹,是通过onTouchEvent来判断是否点击了中间的图标,如果点击了中间图标,水波纹又没开启的话,开启水波纹。
//中间图标区域
private Rect mCenterBitmapArea = new Rect();
//是否开启水波纹
private boolean mIsRuning = false;
//是否点击了中间图标
private boolean mIsCenterClick = false;
@Override
public boolean onTouchEvent(MotionEvent event){
switch (event.getActionMasked()){
case MotionEvent.ACTION_DOWN:
//当按钮只有在图片即按钮区域内则认定为点击,其他不作点击
mIsCenterClick = false;
if (mCenterBitmapArea.contains((int)event.getX(),(int)event.getY())){
mIsCenterClick = true;
}
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (mIsCenterClick && !mIsRuning){
//当点击了按钮,启动水波纹
start();
}
break;
}
return true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mMaxRadius = Math.min(w, h) / 2;
//计算中间图标区域
mCenterBitmapArea.set((w - mCenterBitmap.getWidth()) / 2,(h - mCenterBitmap.getHeight()) / 2
,(w + mCenterBitmap.getWidth()) / 2,(h + mCenterBitmap.getHeight()) / 2);
}
小圆圈WaveCircleView
小圆圈主要是记录x,y的坐标和画一个蓝色的圆圈。
public class WaveCircleView extends View {
//圆圈画笔
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//圆圈颜色
private int mColor = Color.BLUE;
//圆圈半径
private float radius = DisplayUtils.dp2px(getContext(),10);
//在wavelayout的角度
private int layoutX;
//在wavelayout的半径
private int layoutY;
public WaveCircleView(Context context) {
this(context,null);
}
public WaveCircleView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public WaveCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint.setColor(mColor);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL);
}
public int getLayoutX() {
return layoutX;
}
public void setLayoutX(int layoutX) {
this.layoutX = layoutX;
}
public int getLayoutY() {
return layoutY;
}
public void setLayoutY(int layoutY) {
this.layoutY = layoutY;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureSize(widthMeasureSpec), measureSize(heightMeasureSpec));
}
//测量圆圈宽高
private int measureSize(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = DisplayUtils.dp2px(getContext(),radius * 2);
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(radius, radius, radius, mPaint);
}
}
WaveLayout
通过onlayout方法来定位水波纹和小圆圈的位置,首先吧水波纹全屏显示,然后根据随机角度和随机半径一个一个的定位小圆圈的位置。
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
float miniCircleRadius = 0;
//设置水波纹位置
waveView.layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
miniCircleRadius = waveView.getMiniRadius();
int childCount = getChildCount();
//设置circleview
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
//如果不是Circleview跳过
if (!(child instanceof WaveCircleView)) {
continue;
}
WaveCircleView waveCircleView = (WaveCircleView) child;
if (waveCircleView.getLayoutX() == 0 && waveCircleView.getLayoutY() == 0) {
//随机获取角度
double angle = Math.random() * 360;
//随机获取半径,最小半径不能小于WaveView的最小波纹半径
double radians = miniCircleRadius + waveCircleView.getMeasuredWidth() / 2 +
Math.random() * (mWidth / 2 - miniCircleRadius - waveCircleView.getMeasuredWidth() / 2);
//获取WaveCircleView的x坐标
double x = getMeasuredWidth() / 2 + Math.sin(Math.toRadians(angle)) * radians;
//获取WaveCircleView的y坐标
double y = getMeasuredHeight() / 2 + Math.cos(Math.toRadians(angle)) * radians;
waveCircleView.setLayoutX((int) x);
waveCircleView.setLayoutY((int) y);
}
waveCircleView.layout(waveCircleView.getLayoutX(),waveCircleView.getLayoutY(),waveCircleView.getLayoutX() + waveCircleView.getMeasuredWidth(),waveCircleView.getLayoutY() + waveCircleView.getMeasuredHeight());
}
}
android水波圆圈动画,Android支付宝咻咻水波纹效果的实现相关推荐
- html5 水波式按钮_css3+jQuery实现按钮水波纹效果
水波纹按钮 /*自定义按钮样式*/ .btns{ height: 30px; line-height: 30px; text-align: center; width: 200px; color: # ...
- android显示圆圈动画,Android实现3个圆圈的动画
实现了一个类似Windows进度条效果,界面上有三个圆圈,依次有一个圆圈显示白色,其它的圆圈显示蓝色. 画圆圈的View import android.content.Context; import ...
- android显示圆圈动画,android - 在加载stu时在ImageView中使用“动画圆圈”
如果您不想仅仅为了表明进度而膨胀另一个视图,请执行以下操作: 在列表视图的相同XML布局中创建ProgressBar. 让它居中 给它一个id 通过调用setEmptyView将它附加到listvie ...
- android水波纹点击动画,android 控件点击水波纹效果的几种方案
目前我所知道的至少有三种可以实现点击水波纹的效果 第一种:安卓自带的方法 在安卓中有自带的一种属性,可以实现水波纹的效果,就是在所需要点击的控件属性加上如下代码: android:background ...
- android水波效果,android动态壁纸中的水波纹效果
[实例简介] android动态壁纸中的水波纹效果,采用opengl中的shader实现 [实例截图] [核心代码] @Override public String getVertexShader() ...
- android水波纹动画制作,Framer之事件 | 如何制作安卓点击水波纹效果?
之前的 Framer 教程都是按照个人喜好去写的,没有按照难易程度形成系列.为了让大家能更好地入门,我准备由易到难写一个系列教程,尽量保持在每周一篇的频率. 导读:事件是 Framer 中的一个重要概 ...
- Android点击水波纹扩散效果整理(附带一个自定义的水波纹效果控件)
很久很久没有写博客了,说来也有点惭愧.正好最近整理自己的项目工程目录,看到一些值得分享的控件,准备在之后的几篇博客中准备把它们陆续搬运上来. 这篇博客准备整理一下Android Material De ...
- android 立体 流量球,Android自定义View——实现水波纹效果类似剩余流量球
Android自定义View--实现水波纹效果类似剩余流量球 三个点 pre ber block span 初始化 move 理解最近突然手痒就想搞个贝塞尔曲线做个水波纹效 ...
- Android 之自定义view实现水波纹效果
在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她: 在这样的关键时候,身子板就一定得硬了, ...
最新文章
- matlab数值计算好处,第四章 MATLAB 的数值计算功能(一)
- SAP常用的科目字段状态组设置
- MY_Log,无缝替换原生Log,支持日志输出到文件、FirePHP
- SpringBoot AOP完全讲解一:基础概念
- 如何用Python从数据库里面获取数据?4个步骤就能轻松实现
- 实验7.3 字符串 7-7 输出大写英文字母
- python批量解压文件_python 批量解压压缩文件的实例代码
- vue使用@路径引入
- 入职地府后我成了人生赢家_拿年终奖前跳槽,你才是赢家
- Python使用标准库subprocess调用外部程序
- PHP如果某商品下的所有货品库存都为0,则下架该商品
- C语言实现简单的计算器(C语言入门1)
- 处女座的训练(贪心)
- mysql关联分组查询,Mysql 分组查询/子查询/关联查询【总结】
- 卡尔曼滤波 KF | 扩展卡尔曼滤波 EKF (思路流程和计算公式)
- 博士的一天(起早贪黑版本)
- 网页截图及TDK抓取
- Android 仿自如APP裸眼3D效果
- Flutter之开屏广告缓存本地方案(无插件版),兼容 IOS、安卓
- 「万物生长」一个APK从诞生到活跃在Android手机上,android驱动开发权威指南pdf
热门文章
- python卡方分箱_Python评分卡建模—卡方分箱
- Ubuntu 用户切换
- 2018春季-华南理工-计算机概论,【7A文】华南理工大学网络教育学院2018计算机概论作业...
- 鸿蒙系统能在欧洲使用吗,华为能否在欧洲发布鸿蒙系统,然后民间人士推出一键换装安卓?...
- 【高并发】关于乐观锁和悲观锁,蚂蚁金服面试官问了我这几个问题!!
- QListWidget详细使用教程:图标列表显示、右键菜单、自定义item
- Adobe的PDF编辑软件Acrobat Pro DC 2023版本下载与安装教程
- css实现大屏效果的背景div
- 超高清行车记录仪美国高端安霸A7、A5和A2
- Azure 云服务超时问题