Android自定义View实现支付宝咻一咻效果
发布时间 - 2026-01-10 23:07:55 点击率:次本篇文章介绍自定义View配合属性动画来实现如下的效果
实现思路挺简单:
- 画一个半透明的圆
- 实现两种动画效果,点击时扩散和不点击时扩散回收
- 使用线程的方式将上面两步结合起来
首先看下画半透明圆的部分
public class ClickCircleView extends View {
private Bitmap bitmap;
private Paint paint;
private Canvas canvas;
private boolean isSpreadFlag = false;//标记是否发射完成
public boolean isSpreadFlag() {
return isSpreadFlag;
}
public void setIsSpreadFlag(boolean isSpreadFlag) {
this.isSpreadFlag = isSpreadFlag;
}
public ClickCircleView(Context context, int width, int height, int screenWidth, int screenHeight) {
super(context);
bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888); // 设置位图的宽高
canvas = new Canvas();
canvas.setBitmap(bitmap);
paint = new Paint(Paint.DITHER_FLAG);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
paint.setAlpha(50);
canvas.drawCircle(screenWidth / 2, screenHeight / 2, width / 2 + 10, paint);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
可以看到相关的属性都是设置在画笔上,然后直接调用画布的drawCircle()方法画出一个半透明的圆,最后调用invalidate()方法刷新View
一定要重写父类的onDraw()方法,否则自定义View不能生效
我们设置了一个标志位isSpreadFlag,作用是用来标记扩散动画是否完成
然后我们来实现两个动画效果
点击时扩散动画
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:valueFrom="1.0" android:valueTo="1.8" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="1.0" android:valueTo="1.8" android:valueType="floatType" /> </set>
很简单,就是改变scale值,增大到1.8倍
不点击时扩散回收动画
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together"> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="1.0" android:valueTo="1.2" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:valueFrom="1.0" android:valueTo="1.2" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:startOffset="1000" android:valueFrom="1.2" android:valueTo="1.0" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:startOffset="1000" android:valueFrom="1.2" android:valueTo="1.0" android:valueType="floatType" /> </set>
和上个动画类似,startOffset参数可以用来控制Animation的运行顺序,比如Android:startOffset=”1000”表示设置该属性的动画延迟1秒执行
然后就是用线程来执行动画和逻辑的部分了
不点击时的动画部分
mXiuyixiuButton.post(new Runnable() {
@Override
public void run() {
clickCircleView = new ClickCircleView(CustomView1.this, mXiuyixiuButton.getWidth()
, mXiuyixiuButton.getHeight(), mXiuyixiuLayout.getMeasuredWidth(),
mXiuyixiuLayout.getMeasuredHeight());
clickCircleView.setVisibility(View.VISIBLE);
mXiuyixiuLayout.addView(clickCircleView);
mXiuyixiuLayout.postInvalidate();
// 加载动画
final Animator anim = AnimatorInflater.loadAnimator(CustomView1.this,
R.animator.circle_scale_animator);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (anim != null) {
anim.start();//循环执行动画
}
}
});
anim.setTarget(clickCircleView);
anim.start();
}
});
初始化好clickCircleView之后将这个view加入父布局中,然后加载动画并设置循环执行,最后使用postInvalidate()在子线程中刷新view
点击时的动画部分
mXiuyixiuButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickCircleView.setVisibility(View.GONE);//发射圆圈,即将循环动画View隐藏
final ClickCircleView item = new ClickCircleView(CustomView1.this, mXiuyixiuButton.getWidth()
, mXiuyixiuButton.getHeight(), mXiuyixiuLayout.getWidth(),
mXiuyixiuLayout.getHeight());
Animator spreadAnim = AnimatorInflater.loadAnimator(CustomView1.this,
R.animator.circle_spread_animator);
spreadAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
item.setIsSpreadFlag(true);//动画执行完成,标记一下
}
});
spreadAnim.setTarget(item);
spreadAnim.start();
clickCircleViewList.add(item);
mXiuyixiuLayout.addView(item);
mXiuyixiuLayout.invalidate();
handler.post(circleViewRunnable);
}
});
隐藏不点击动画,初始化好ClickCircleView后将该view加入List中并添加到父布局中,然后加载动画并在动画结束时添加isSpreadFlag标记,最后调用invalidate()方法刷新view并开启线程
线程部分
private Runnable circleViewRunnable = new Runnable() {
public void run() {
for (int i = 0; i < clickCircleViewList.size(); i++) {
if (clickCircleViewList.get(i).isSpreadFlag()) {
mXiuyixiuLayout.removeView(clickCircleViewList.get(i));
clickCircleViewList.remove(i);
mXiuyixiuLayout.postInvalidate();
}
}
if (clickCircleViewList.size() <= 0) {
clickCircleView.setVisibility(View.VISIBLE);
}
handler.postDelayed(this, 100);
}
};
遍历list,将有isSpreadFlag标记的view从list和父布局中移除并刷新view,最后判断list如果为空的话将不点击时的动画显示出来
最后记得在onDestroy()里移除线程
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(circleViewRunnable);
}
使用自定义View配合属性动画来实现该效果耦合性较高,只是这种方式相比完全使用自定义View来说更加流畅,该方式大部分参考别人博客上的代码来实现,但是如果仅仅只是就拿来用不总结是不会成为自己的知识的,因此有了这篇博客。
参考: android实现支付宝咻一咻的几种思路方法
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Android
# 支付宝
# 咻一咻
# Android 自定义view仿支付宝咻一咻功能
# Android中RecyclerView布局代替GridView实现类似支付宝的界面
# Android波纹扩散效果之仿支付宝咻一咻功能实现波纹扩散特效
# Android app第三方支付宝支付接入教程
# Android支付宝支付封装代码
# Android支付宝和微信支付集成
# Android开发之实现GridView支付宝九宫格
# Android仿支付宝支付从底部弹窗效果
# Android支付宝支付设计开发
# 支付宝咻一咻怎么用 Android帮你实现咻一咻
# 自定义
# 来实现
# 加载
# 移除
# 自己的
# 都是
# 两种
# 遍历
# 并在
# 较高
# 博客
# 很简单
# 可以看到
# 几种
# 重写
# 将有
# 后将
# 这篇
# 结合起来
# 上个
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
JavaScript中的标签模板是什么_它如何扩展字符串功能
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
浅述节点的创建及常见功能的实现
JavaScript如何实现音频处理_Web Audio API如何工作?
在centOS 7安装mysql 5.7的详细教程
nginx修改上传文件大小限制的方法
iOS UIView常见属性方法小结
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】
如何快速建站并高效导出源代码?
网易LOFTER官网链接 老福特网页版登录地址
Laravel如何配置和使用缓存?(Redis代码示例)
在线制作视频网站免费,都有哪些好的动漫网站?
Android仿QQ列表左滑删除操作
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
Laravel API资源类怎么用_Laravel API Resource数据转换
简单实现Android文件上传
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
Laravel观察者模式如何使用_Laravel Model Observer配置
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
详解Android——蓝牙技术 带你实现终端间数据传输
如何使用 jQuery 正确渲染 Instagram 风格的标签列表
b2c电商网站制作流程,b2c水平综合的电商平台?
如何注册花生壳免费域名并搭建个人网站?
深入理解Android中的xmlns:tools属性
如何挑选优质建站一级代理提升网站排名?
详解jQuery中基本的动画方法
Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
微信小程序 input输入框控件详解及实例(多种示例)
再谈Python中的字符串与字符编码(推荐)
魔方云NAT建站如何实现端口转发?
如何在香港服务器上快速搭建免备案网站?
瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
北京的网站制作公司有哪些,哪个视频网站最好?
如何用VPS主机快速搭建个人网站?
Laravel怎么在Controller之外的地方验证数据
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
C++用Dijkstra(迪杰斯特拉)算法求最短路径
高端网站建设与定制开发一站式解决方案 中企动力
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
iOS验证手机号的正则表达式

