Android 自定义控件之圆形扩散View(DiffuseView)

实现效果

使用

XML中:

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

代码中:

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 = 150;
    /** 扩散圆宽度 */
    private int mDiffuseWidth = 3;
    /** 最大宽度 */
    private Integer mMaxWidth = 255;
    /** 是否正在扩散中 */
    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, -1);
    }

    public DiffuseView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

       TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DiffuseView, defStyleAttr, 0);
        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, -1);
        if(imageId != -1) mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
        a.recycle();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mAlphas.add(255);
        mWidths.add(0);
    }

    @Override
    public void invalidate() {
        if(hasWindowFocus()){
            super.invalidate();
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        // 绘制扩散圆
        mPaint.setColor(mColor);
        for (int i = 0; i < mAlphas.size(); i++) {
            // 设置透明度
            Integer alpha = mAlphas.get(i);
            mPaint.setAlpha(alpha);
            // 绘制扩散圆
            Integer width = mWidths.get(i);
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, mCoreRadius + width, mPaint);

            if(alpha > 0 && width < mMaxWidth){
                mAlphas.set(i, alpha - 1);
                mWidths.set(i, width + 1);
            }
        }
        // 判断当扩散圆扩散到指定宽度时添加新扩散圆
        if (mWidths.get(mWidths.size() - 1) == mMaxWidth / mDiffuseWidth) {
            mAlphas.add(255);
            mWidths.add(0);
        }
        // 超过10个扩散圆,删除最外层
        if(mWidths.size() >= 10){
            mWidths.remove(0);
            mAlphas.remove(0);
        }

        // 绘制中心圆及图片
        mPaint.setAlpha(255);
        mPaint.setColor(mCoreColor);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mCoreRadius, mPaint);

        if(mBitmap != null){
            canvas.drawBitmap(mBitmap, getWidth() / 2 - mBitmap.getWidth() / 2
                    , getHeight() / 2 - mBitmap.getHeight() / 2, 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

时间: 2024-12-25 11:14:56

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

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

转载请注明地址:http://blog.csdn.net/ethan_xue/article/details/7313788 ps: 可根据apidemo里LableView,list4,list6学习 文档在dev guide/Framework Topics/User Interface/Building Custom Components 自定义控件的步骤: 1 View的工作原理  2 编写View类  3 为View类增加属性  4 绘制屏幕  5 响应用户消息  6 自定义回调函数

android自定义控件之圆形头像

一.自定义控件1 首先创建一个继承ImageView的抽象类MaskedImage.让他重写onDraw方法.代码如下 import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.Por

Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

最近在Github上看到了daimajia写的一个开源组件NumberProgressBar觉得非常好,故而在其基础上进行了一些延伸与扩展,编写了一个NumberCircleProgressBar(即圆形的进度条),并且分为两种模式,我称之为rotate模式和rising_water模式. PS:也许本文介绍的方法不是最优(比如游戏开发中可能只需要调用一个方法即可完成),也可能会有纰漏,所以请读者海涵! NumberCircleProgressBar的样图如下: Rotate模式     Ris

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

From:http://blog.csdn.net/xiadik/article/details/41648181package com.wangran.beautiful_girl_show.view; import com.wangran.beautiful_girl_show.view.photoview.PhotoView; import android.content.Context; import android.graphics.Canvas; import android.gra

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

1前言 最近做项目的时候遇到一个卡劵的效果,由于自己觉得用图片来做的话可以会出现适配效果不好,再加上自己自定义view方面的知识比较薄弱,所以想试试用自定义View来实现.但是由于自己知识点薄弱,一开始居然想着用画矩形来设置边缘实现,后面一个哥们指导了我,在这里感谢他. 2实现分析 上面的图片其实和普通的Linearlayout,RelativeLayout一样,只是上下两边多了类似于半圆锯齿的形状.那么只需要处理不同地方.可以在上下两条线上画一个个白色的小圆来实现这种效果. 假如我们上下线的半

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

在做Android平台开发的时候,经常会遇到安卓原生控件无法满足需求的情况,安卓允许开发者去继承已经存在的控件或者实现你自己的控件. 先来看一下效果图 采用直接集成View类,重写onDrow方法绘制. 下面附上主要代码. 1 新建一个类CircleView 继承自View 1 package com.lennon.view; 2 3 import android.content.Context; 4 import android.graphics.Canvas; 5 import androi

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

不少人应该见过小米手机系统音量控制UI,一个圆形带动画效果的音量加减UI,效果很好看.它是怎么实现的呢?这篇博客来揭开它的神秘面纱.先上效果图 相信很多人都知道Android自定义控件的三种方式,Android自定义控件View(一)自绘控件,Android自定义控件View(二)继承控件,还有就是这一节即将学习到的组合控件.我们通过实现圆形音量UI来讲解组合控件的定义和使用. 组合控件 所谓组合控件就是有多个已有的控件组合而成一个复杂的控件.比如上图的音量控件就是一个完美的组合控件.我们来分析

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

一.概述 在上一篇博文中,我们给大家介绍了Android自定义控件系列的基础篇.链接:http://www.cnblogs.com/jerehedu/p/4360066.html 这一篇博文中,我们将在基础篇的基础上,再通过重写ondraw()方法和自定义属性实现圆形进度条,效果如图所示: 二.实现步骤   1.  编写自定义组件MyCircleProgress扩展View public class MyCircleProgress extends View { - } 2.  在MyCircl

Android自定义控件View(二)

在前一篇博客中学习了Android自定义控件View的流程步骤和注意点,不了解的童鞋可以参考Android自定义控件View(一).这一节开始学习自定义控件View(二)之继承系统已有的控件.我们来自定义一个圆形ImageView. RoundImageView 随着Android UI效果越来越炫,很多系统自带的控件已经无法满足日常开发需求,比如很多应用的头像是圆形的,QQ头像就是圆形的图片.但是Android系统提供的控件当中没有一个是圆形的.那么怎么才能实现圆形头像效果呢?两种方法: 图片