博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 两种方式实现类似水波扩散效果
阅读量:5743 次
发布时间:2019-06-18

本文共 4732 字,大约阅读时间需要 15 分钟。

image

两种方式实现类似水波扩散效果,先上图为敬

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

自定义view实现

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

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

style文件里自定义属性

初始化

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);    //最开始不透明且扩散距离为0    alphas.add(255);    spreadRadius.add(0);    spreadPaint = new Paint();    spreadPaint.setAntiAlias(true);    spreadPaint.setAlpha(255);    spreadPaint.setColor(spreadColor);}

确定圆心位置

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

自定义view的绘制

@Overrideprotected 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样式

效果图

image

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

动画实现

思路分析:通过动画实现,imageView不停做动画缩放+渐变

最中心的imageView保持不变
中间一层imageView从原始放大到1.4倍,同时从不透明变为半透明
最外层的imageView从1.4倍放大到1.8倍,同时从半透明变为全透明
利用shape画一个圆,作为动画基础视图

布局视图

中间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);}

效果图

image

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

两种方式实现的扩散效果介绍完毕,具体项目里还是要按需变动的。

同时欢迎关注微信公众号

image.png

转载地址:http://lrizx.baihongyu.com/

你可能感兴趣的文章
单元测试
查看>>
spring.net 继承
查看>>
ES6:模块简单解释
查看>>
JavaScript indexOf() 方法
查看>>
用Bootstrap写一份简历
查看>>
ZJU PAT 1023
查看>>
WMI远程访问问题解决方法
查看>>
从零开始学习IOS,(UILabel控件)详细使用和特殊效果
查看>>
Android开发历程_15(AppWidget的使用)
查看>>
阿花宝宝 Java 笔记 之 初识java
查看>>
7、设计模式-创建型模式-建造者模式
查看>>
Cesium官方教程11--建模人员必读
查看>>
我国古代的勾股定理
查看>>
Linux下的C编程实战
查看>>
[32期] html中部分代码与英语单词关系
查看>>
PHP安装环境,服务器不支持curl_exec的解决办法
查看>>
jQuery|元素遍历
查看>>
RedHat 6 安装配置Apache 2.2
查看>>
Openstack 安装部署指南翻译系列 之 Manila服务安装(Share Storage)
查看>>
underscore.js学习笔记
查看>>