当前位置: 首页 > news >正文

Android 两种方式实现类似水波扩散效果

两种方式实现类似水波扩散效果,(相比较而言,自定义view的效果更好点,动画实现起来更方便点。)

  1. 自定义view实现
  2. 动画实现

自定义view实现

思路分析:通过canvas画圆,每次改变圆半径和透明度,当半径达到一定程度,再次从中心开始绘圆,达到不同层级的效果,通过不断绘制达到view扩散效果

private Paint centerPaint; //中心圆paint
private int radius = 100; //中心圆半径
private Paint spreadPaint; //扩散圆paint
private float centerX;//圆心x
private float centerY;//圆心y
private int distance = 5; //每次圆递增间距
private int maxRadius = 80; //最大圆半径
private int delayMilliseconds = 33;//扩散延迟间隔,越大扩散越慢
private List<Integer> spreadRadius = new ArrayList<>();//扩散圆层级数,元素为扩散的距离
private List<Integer> alphas = new ArrayList<>();//对应每层圆的透明度

style文件里自定义属性

<declare-styleable name="SpreadView"><!--中心圆颜色--><attr name="spread_center_color" format="color" /><!--中心圆半径--><attr name="spread_radius" format="integer" /><!--扩散圆颜色--><attr name="spread_spread_color" format="color" /><!--扩散间距--><attr name="spread_distance" format="integer" /><!--扩散最大半径--><attr name="spread_max_radius" format="integer" /><!--扩散延迟间隔--><attr name="spread_delay_milliseconds" format="integer" />
</declare-styleable>

初始化

public SpreadView(Context context) {this(context, null, 0);
}public SpreadView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);
}public SpreadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpreadView, defStyleAttr, 0);radius = a.getInt(R.styleable.SpreadView_spread_radius, radius);maxRadius = a.getInt(R.styleable.SpreadView_spread_max_radius, maxRadius);int centerColor = a.getColor(R.styleable.SpreadView_spread_center_color, ContextCompat.getColor(context, R.color.colorAccent));int spreadColor = a.getColor(R.styleable.SpreadView_spread_spread_color, ContextCompat.getColor(context, R.color.colorAccent));distance = a.getInt(R.styleable.SpreadView_spread_distance, distance);a.recycle();centerPaint = new Paint();centerPaint.setColor(centerColor);centerPaint.setAntiAlias(true);//最开始不透明且扩散距离为0alphas.add(255);spreadRadius.add(0);spreadPaint = new Paint();spreadPaint.setAntiAlias(true);spreadPaint.setAlpha(255);spreadPaint.setColor(spreadColor);
}

确定圆心位置

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);//圆心位置centerX = w / 2;centerY = h / 2;
}

自定义view的绘制

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);for (int i = 0; i < spreadRadius.size(); i++) {int alpha = alphas.get(i);spreadPaint.setAlpha(alpha);int width = spreadRadius.get(i);//绘制扩散的圆canvas.drawCircle(centerX, centerY, radius + width, spreadPaint);//每次扩散圆半径递增,圆透明度递减if (alpha > 0 && width < 300) {alpha = alpha - distance > 0 ? alpha - distance : 1;alphas.set(i, alpha);spreadRadius.set(i, width + distance);}}//当最外层扩散圆半径达到最大半径时添加新扩散圆if (spreadRadius.get(spreadRadius.size() - 1) > maxRadius) {spreadRadius.add(0);alphas.add(255);}//超过8个扩散圆,删除最先绘制的圆,即最外层的圆if (spreadRadius.size() >= 8) {alphas.remove(0);spreadRadius.remove(0);}//中间的圆canvas.drawCircle(centerX, centerY, radius, centerPaint);//TODO 可以在中间圆绘制文字或者图片//延迟更新,达到扩散视觉差效果postInvalidateDelayed(delayMilliseconds);
}

xml样式

<com.airsaid.diffuseview.widget.SpreadViewandroid:id="@+id/spreadView"android:layout_width="match_parent"android:layout_height="wrap_content"app:spread_center_color="@color/colorAccent"app:spread_delay_milliseconds="35"app:spread_distance="5"app:spread_max_radius="90"app:spread_radius="100"app:spread_spread_color="@color/colorAccent" />

中心圆处可以自定义写文字,画图片等等...

动画实现

思路分析:通过动画实现,imageView不停做动画缩放+渐变
最中心的imageView保持不变
中间一层imageView从原始放大到1.4倍,同时从不透明变为半透明
最外层的imageView从1.4倍放大到1.8倍,同时从半透明变为全透明
利用shape画一个圆,作为动画基础视图

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><corners android:radius="65dp"/><solid android:color="@color/colorAccent"/>
</shape>

布局视图

<FrameLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><!--中心imageView--><ImageViewandroid:id="@+id/iv_wave"android:layout_width="130dp"android:layout_height="130dp"android:layout_gravity="center"android:background="@drawable/shape_circle" /><!--中间的imageView--><ImageViewandroid:id="@+id/iv_wave_1"android:layout_width="130dp"android:layout_height="130dp"android:layout_gravity="center"android:background="@drawable/shape_circle" /><!--最外层imageView--><ImageViewandroid:id="@+id/iv_wave_2"android:layout_width="130dp"android:layout_height="130dp"android:layout_gravity="center"android:background="@drawable/shape_circle" />
</FrameLayout>

中间imageView的动画

private void setAnim1() {AnimationSet as = new AnimationSet(true);//缩放动画,以中心从原始放大到1.4倍ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.4f, 1.0f, 1.4f,ScaleAnimation.RELATIVE_TO_SELF, 0.5f,ScaleAnimation.RELATIVE_TO_SELF, 0.5f);//渐变动画AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.5f);scaleAnimation.setDuration(800);scaleAnimation.setRepeatCount(Animation.INFINITE);alphaAnimation.setRepeatCount(Animation.INFINITE);as.setDuration(800);as.addAnimation(scaleAnimation);as.addAnimation(alphaAnimation);iv1.startAnimation(as);
}

最外层imageView的动画

private void setAnim2() {AnimationSet as = new AnimationSet(true);//缩放动画,以中心从1.4倍放大到1.8倍ScaleAnimation scaleAnimation = new ScaleAnimation(1.4f, 1.8f, 1.4f, 1.8f,ScaleAnimation.RELATIVE_TO_SELF, 0.5f,ScaleAnimation.RELATIVE_TO_SELF, 0.5f);//渐变动画AlphaAnimation alphaAnimation = new AlphaAnimation(0.5f, 0.1f);scaleAnimation.setDuration(800);scaleAnimation.setRepeatCount(Animation.INFINITE);alphaAnimation.setRepeatCount(Animation.INFINITE);as.setDuration(800);as.addAnimation(scaleAnimation);as.addAnimation(alphaAnimation);iv2.startAnimation(as);
}

相比较而言,自定义view的效果更好点,动画实现起来更方便点。

http://www.lryc.cn/news/468351.html

相关文章:

  • 基于SSM+小程序的垃圾分类管理系统(垃圾2)
  • 微服务网格Istio介绍
  • 【MySQL】视图与用户管理——MySQL
  • Go语言中三个输入函数(scanf,scan,scanln)的区别
  • uniapp使用html2canvas时,页面内的image元素模糊
  • 华为交换机堆叠
  • Spring Boot框架下中小企业设备管理系统开发
  • 鸿蒙开发融云demo消息未读数
  • 非对称加密算法(RSA):原理、应用与代码实现
  • docker部署SQL审核平台Archery
  • ceph 删除rbd 锁的命令
  • MySQL【知识改变命运】01
  • 苍穹外卖 Maven依赖配置
  • Lucas带你手撕机器学习——SVM支持向量机
  • 将后端返回的网络url转成blob对象,实现pdf预览
  • 民峰金融智能交易模型的应用与未来趋势
  • 文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑负荷时空迁移的5G基站与配电网协同优化运行 》
  • 数据结构中的堆(Heap)
  • Linux误删文件找回
  • 深入计算机语言之C++:类与对象(中)
  • 51单片机快速入门之 IIC I2C通信
  • 腾讯推出ima.copilot智能工作台产品 由混元大模型提供技术支持
  • 1024是什么日子
  • 驱动开发系列20 - Linux Graphics Xorg-server 介绍
  • 晶台推出SOP5封装的高速光耦KLM45X,提供1MBit/s超快速率
  • 软物质流变探究:从宏观微观差异,到水凝胶界面特性
  • Axure中继器单选、多选和重置
  • 微软公司用没有使用证据的商标申请驰名商标,该怎么维权?
  • 学习分布式系统我来助你!【基本知识、基础理论、设计模式、应用场景、工程应用、缓存等全包含!】
  • ubuntu查看系统版本命令