实现效果

使用

XML中:

<com.airsaid.diffuseview.widget.DiffuseView
android:id="@+id/diffuseView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=""
app:diffuse_color="@color/colorAccent"
app:diffuse_coreColor="@color/colorPrimaryDark"
app:diffuse_coreImage="@android:drawable/ic_menu_search"
app:diffuse_coreRadius=""
app:diffuse_maxWidth=""
app:diffuse_width=""/>

代码中:

DiffuseView mDiffuseView = (DiffuseView) findViewById(R.id.diffuseView);
mDiffuseView.start(); // 开始扩散
mDiffuseView.stop();// 停止扩散

属性&方法

属性名 java方法 作用
diffuse_color setColor(int colorId) 设置扩散圆颜色
diffuse_coreColor setCoreColor(int colorId) 设置中心圆颜色
diffuse_coreImage setCoreImage(int imageId) 设置中心圆图片
diffuse_coreRadius setCoreRadius(int radius) 设置中心圆半径
diffuse_maxWidth setMaxWidth(int maxWidth) 设置最大扩散宽度
diffuse_width setDiffuseWidth(int width) 设置扩散圆宽度,值越小越宽

代码

/**
* Created by zhouyou on 2016/9/27.
* Class desc:
*
* 这是一个自定义圆圈扩散View
*/
public class DiffuseView extends View { /** 扩散圆圈颜色 */
private int mColor = getResources().getColor(R.color.colorAccent);
/** 圆圈中心颜色 */
private int mCoreColor = getResources().getColor(R.color.colorPrimary);
/** 圆圈中心图片 */
private Bitmap mBitmap;
/** 中心圆半径 */
private float mCoreRadius = ;
/** 扩散圆宽度 */
private int mDiffuseWidth = ;
/** 最大宽度 */
private Integer mMaxWidth = ;
/** 是否正在扩散中 */
private boolean mIsDiffuse = false;
// 透明度集合
private List<Integer> mAlphas = new ArrayList<>();
// 扩散圆半径集合
private List<Integer> mWidths = new ArrayList<>();
private Paint mPaint; public DiffuseView(Context context) {
this(context, null);
} public DiffuseView(Context context, AttributeSet attrs) {
this(context, attrs, -);
} public DiffuseView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DiffuseView, defStyleAttr, );
mColor = a.getColor(R.styleable.DiffuseView_diffuse_color, mColor);
mCoreColor = a.getColor(R.styleable.DiffuseView_diffuse_coreColor, mCoreColor);
mCoreRadius = a.getFloat(R.styleable.DiffuseView_diffuse_coreRadius, mCoreRadius);
mDiffuseWidth = a.getInt(R.styleable.DiffuseView_diffuse_width, mDiffuseWidth);
mMaxWidth = a.getInt(R.styleable.DiffuseView_diffuse_maxWidth, mMaxWidth);
int imageId = a.getResourceId(R.styleable.DiffuseView_diffuse_coreImage, -);
if(imageId != -) mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
a.recycle();
} private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mAlphas.add();
mWidths.add();
} @Override
public void invalidate() {
if(hasWindowFocus()){
super.invalidate();
}
} @Override
public void onDraw(Canvas canvas) {
// 绘制扩散圆
mPaint.setColor(mColor);
for (int i = ; i < mAlphas.size(); i++) {
// 设置透明度
Integer alpha = mAlphas.get(i);
mPaint.setAlpha(alpha);
// 绘制扩散圆
Integer width = mWidths.get(i);
canvas.drawCircle(getWidth() / , getHeight() / , mCoreRadius + width, mPaint); if(alpha > && width < mMaxWidth){
mAlphas.set(i, alpha - );
mWidths.set(i, width + );
}
}
// 判断当扩散圆扩散到指定宽度时添加新扩散圆
if (mWidths.get(mWidths.size() - ) == mMaxWidth / mDiffuseWidth) {
mAlphas.add();
mWidths.add();
}
// 超过10个扩散圆,删除最外层
if(mWidths.size() >= ){
mWidths.remove();
mAlphas.remove();
} // 绘制中心圆及图片
mPaint.setAlpha();
mPaint.setColor(mCoreColor);
canvas.drawCircle(getWidth() / , getHeight() / , mCoreRadius, mPaint); if(mBitmap != null){
canvas.drawBitmap(mBitmap, getWidth() / - mBitmap.getWidth() /
, getHeight() / - mBitmap.getHeight() / , mPaint);
} if(mIsDiffuse){
invalidate();
}
} /**
* 开始扩散
*/
public void start() {
mIsDiffuse = true;
invalidate();
} /**
* 停止扩散
*/
public void stop() {
mIsDiffuse = false;
} /**
* 是否扩散中
*/
public boolean isDiffuse(){
return mIsDiffuse;
} /**
* 设置扩散圆颜色
*/
public void setColor(int colorId){
mColor = colorId;
} /**
* 设置中心圆颜色
*/
public void setCoreColor(int colorId){
mCoreColor = colorId;
} /**
* 设置中心圆图片
*/
public void setCoreImage(int imageId){
mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
} /**
* 设置中心圆半径
*/
public void setCoreRadius(int radius){
mCoreRadius = radius;
} /**
* 设置扩散圆宽度(值越小宽度越大)
*/
public void setDiffuseWidth(int width){
mDiffuseWidth = width;
} /**
* 设置最大宽度
*/
public void setMaxWidth(int maxWidth){
mMaxWidth = maxWidth;
}
}

源码下载

GitHub:https://github.com/Airsaid/DiffuseView

Android 自定义控件之圆形扩散View(DiffuseView)的更多相关文章

  1. Android - 自定义控件之圆形控件

    自定义控件 - 圈圈 Android L: Android Studio 效果:能够自定义圆圈半径和位置:设定点击效果:改变背景颜色 下面是demo图 点击前: 点击后: 自定义控件一般要继承View ...

  2. android自定义控件(二) 入门,继承View

    转载请注明地址:http://blog.csdn.net/ethan_xue/article/details/7313788 ps: 可根据apidemo里LableView,list4,list6学 ...

  3. Android自定义控件之圆形进度条ImageView

    From:http://blog.csdn.net/xiadik/article/details/41648181package com.wangran.beautiful_girl_show.vie ...

  4. 一起来学习android自定义控件—边缘凹凸的View

    1前言 最近做项目的时候遇到一个卡劵的效果,由于自己觉得用图片来做的话可以会出现适配效果不好,再加上自己自定义view方面的知识比较薄弱,所以想试试用自定义View来实现.但是由于自己知识点薄弱,一开 ...

  5. Android实现边缘凹凸的View

    转载 最近做项目的时候遇到一个卡劵的效果,由于自己觉得用图片来做的话可以会出现适配效果不好,再加上自己自定义view方面的知识比较薄弱,所以想试试用自定义View来实现.但是由于自己知识点薄弱,一开始 ...

  6. Android自定义控件系列之应用篇——圆形进度条

    一.概述 在上一篇博文中,我们给大家介绍了Android自定义控件系列的基础篇.链接:http://www.cnblogs.com/jerehedu/p/4360066.html 这一篇博文中,我们将 ...

  7. android 自定义控件---圆形方向盘

    在做Android平台开发的时候,经常会遇到安卓原生控件无法满足需求的情况,安卓允许开发者去继承已经存在的控件或者实现你自己的控件. 先来看一下效果图 采用直接集成View类,重写onDrow方法绘制 ...

  8. Android自定义控件View(三)组合控件

    不少人应该见过小米手机系统音量控制UI,一个圆形带动画效果的音量加减UI,效果很好看.它是怎么实现的呢?这篇博客来揭开它的神秘面纱.先上效果图 相信很多人都知道Android自定义控件的三种方式,An ...

  9. Android自定义控件View(二)继承控件

    在前一篇博客中学习了Android自定义控件View的流程步骤和注意点,不了解的童鞋可以参考Android自定义控件View(一).这一节开始学习自定义控件View(二)之继承系统已有的控件.我们来自 ...

随机推荐

  1. PAT_A1122#Hamiltonian Cycle

    Source: PAT A1122 Hamiltonian Cycle (25 分) Description: The "Hamilton cycle problem" is to ...

  2. Selenium三种等待的使用方式

    在UI自动化测试中,必然会遇到环境不稳定,网络慢的情况,这时如果你不做任何处理的话,代码会由于没有找到元素,而报错.这时我们就要用到wait(等待),而在Selenium中,我们可以用到一共三种等待, ...

  3. 【剑指Offer】11、二进制中1的个数

      题目描述:   输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示.   解题思路:   本题有以下两个解决方案:   (1)依次判断每一位.判断的方法是先与1相与,为1则说明该位为1 ...

  4. Java语言输出HelloWorld

    1.新建一个名为HelloWorld.txt的文本文件. 2.将HelloWorld.txt改为.java. 3.将HelloWorld.java用文本文件的方式打开,并输入代码. 4.打开命令行,进 ...

  5. 亚马逊免费服务器搭建Discuz!论坛过程(一)

    1:申请 目前亚马逊服务器免费12个月,需要一张信用卡即可免费注册领取. 地址:https://aws.amazon.com/cn/free/ 2: 创建实例 2.1进入控制台:https://ap- ...

  6. vue 封装axios以及使用中间代理 proxy

    为什么需要封装呢?主要是为了更好管理项目以及增加复用性 1.首先在src文件夹下创建api文件夹 . utils文件夹 . server文件夹 api:创建一个index.js文件   用来存放接口地 ...

  7. Ubuntu下ss的安装与使用

    不得不说,linux真的有种让人用上就爱上的魔力,正好最近Ubuntu出了16.04,便索性装了个win10+Ubuntu的双系统,也算是告慰那永远留在老硬盘里的虚拟机吧. 言归正传,换上Ubuntu ...

  8. ArcEngine 地图导航 查找路径 经纬度坐标导航 最优路径分析

    本文来自CSDN博客.转载请标明出处 http//blog.csdn.net/zdb330906531 需求:依据经纬度坐标.取得两个起点与终点,显示最优路径实现导航. 參考官方样例后.我在arcMa ...

  9. Struts2 动态结果集

    1.index.jsp <body> 动态结果 一定不要忘了为动态结果的保存值设置set get方法 <ol> <li><a href="user/ ...

  10. swift 笔记 (十四) —— 构造过程

    构造过程 为了生成类.结构体.枚举等的实例,而做的准备过程,叫做构造过程. 为了这个过程,我们一般会定义一个方法来完毕,这种方法叫做构造器.当然它的逆过程,叫做析构器,用于在实例被释放前做一些清理工作 ...