代码:

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator; import net.wt.gate.dev.libs.log.L; import java.util.concurrent.CopyOnWriteArrayList; public class DoorBellAnimal extends View {
private int centerX;
private int centerY;
private int startRadius = 10;
private int endRadius = 250;
private int startAlpha = 250; private CopyOnWriteArrayList<RippleCircle> rippleCircles = new CopyOnWriteArrayList<>(); public DoorBellAnimal(Context context) {
this(context, null);
} public DoorBellAnimal(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
} public DoorBellAnimal(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); } @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec); centerX = width / 2;
centerY = height / 2;
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); for (RippleCircle circle : rippleCircles) {
circle.draw(canvas);
} } @Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
startRipple();
startAnimal(); } private void startRipple() {
postOnAnimationDelayed(() -> { RippleCircle rippleCircle = new RippleCircle();
rippleCircles.add(rippleCircle);
startRipple();
}, 500); } private ValueAnimator valueAnimator; @Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
valueAnimator.cancel();
valueAnimator.end();
} private void startAnimal() {
valueAnimator = ValueAnimator.ofInt(0, 60);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setDuration(3000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.setRepeatMode(ValueAnimator.RESTART); valueAnimator.addUpdateListener(animation -> postInvalidateOnAnimation());
valueAnimator.start(); } /**
* 需要画的 圆圈,需要不断改变半径何透明度
*/
private class RippleCircle { private Paint paint; //画笔
private int progress; //当前进度 private int perRadius = (endRadius - startRadius) / 60;
private int perAlpha = startAlpha / 60; RippleCircle() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
progress = 0;
} void draw(Canvas canvas) { if (paint == null) {
return;
}
if (progress >= 60) {
rippleCircles.remove(this);
return;
}
progress++;
float currentAlpha = startAlpha - perAlpha * progress;
paint.setAlpha((int) (currentAlpha)); //更改透明度
float current = startRadius + perRadius * progress;
canvas.drawCircle(centerX, centerY, current, paint);
}
} }

 

Android开发 自定义View_白色圆型涟漪动画View的更多相关文章

  1. Android开发自定义View

    Android中View组件的作用类似于Swing变成中的JPanel,它只是一个空白的矩形区域,View组件中没有任何内容.对于Android应用的其他UI组件来说,它们都继承了View组件,然后在 ...

  2. android 开发-自定义多节点进度条显示

    看效果图: 里面的线段颜色和节点图标都是可以自定义的. main.xml <RelativeLayout xmlns:android="http://schemas.android.c ...

  3. [android 开发篇] 易白教程网址

    http://www.yiibai.com/android/android_bluetooth.html

  4. android开发 自定义图文混排控件

    功能:图文混排,可自动缩放字体,如图: 单点触控使用的代码来自:http://blog.csdn.net/xiaanming/article/details/42833893  谢谢博主! 在该dem ...

  5. Android开发之仿微信显示更多文字的View

    最近开发需求中要模仿微信朋友圈文章的展开收起功能,网上找了找,发现都有问题,于是乎自己在前辈的基础上进行了一定量的修改,下边将源码贴出来供大家参考:1.主Activity布局文件就不粘贴了,很简单,就 ...

  6. Android开发 - 掌握ConstraintLayout(十一)复杂动画!如此简单!

    介绍 本系列我们已经介绍了ConstraintLayout的基本用法.学习到这里,相信你已经熟悉ConstraintLayout的基本使用了,如果你对它的用法还不了解,建议您先阅读我之前的文章. 使用 ...

  7. Android开发UI之给ListView设置布局动画效果

    1.通过JAVA代码添加,资源文件基本上不修改 XML文件,只添加了一个ListView,就不贴XML文件的代码了. java代码: public class MainActivity extends ...

  8. Android开发之自定义组件和接口回调

    说到自定义控件不得不提的就是接口回调,在Android开发中接口回调用的还是蛮多的.在这篇博客开始的时候呢,我想聊一下iOS的自定义控件.在iOS中自定义控件的思路是继承自UIView, 在UIVie ...

  9. 在Eclipse下搭建Android开发环境教程

    我们昨天向各位介绍了<在NetBeans上搭建Android SDK环境>,前不久也介绍过<在MyEclipse 8.6上搭建Android开发环境>, 都受到了读者的欢迎.但 ...

随机推荐

  1. VC++ 2010 创建高级Ribbon界面详解(2)

    Ribbon 控件的使用 1.命令按钮 命令按钮可以说是我们最常用的Ribbon控件了,我们通常都是通过命令按钮来发送某个命令,执行某个动作.它代替了过去的菜单命令,成为使用最频繁的Ribbon控件. ...

  2. css渐变写法 从左到右渐变三种颜色示例;

    background:linear-gradient(to right,#7f06a8,#a02bc2,#7f06a8)

  3. BBS论坛 文章详情、点赞、评论

    六.文章详情.点赞.评论 文章详情页面: def article_detail(request, username, article_id): # user_obj = models.UserInfo ...

  4. 编写Storm程序

  5. C#编程入门--MYSQLHELPER

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  6. 用selenium 自动爬取某一本小说章节及其内容,并存入数据库中

    from selenium import webdriver import pymysql from selenium.webdriver.support.ui import WebDriverWai ...

  7. leetcode-159周赛-5231-删除子文件夹

    题目描述: 自己的提交: class Solution: def removeSubfolders(self, folder: List[str]) -> List[str]: d = {} r ...

  8. leetcood学习笔记-39-组合总和

    题目描述: 方法一: class Solution: def combinationSum(self, candidates, target): """ :type ca ...

  9. bzoj1026题解

    [解题思路] 数位DP.f[i][j]表示以j结尾的i位数中windy数的个数,转移方程f[i][j]=Σf[i-1][k](|j-k|>1). 基于f数组,我们可以统计出1~n内的windy数 ...

  10. 6 Accessing and Managing Symbols with armlink

    6.4 Image$$ execution region symbols The linker generates Image$$ symbols for every execution region ...