Android 自定义扩散圆_android自定义view 实现圆的扩散-程序员宅基地

技术标签: java  android  

package com.example.cloud;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import java.util.ArrayList;
import java.util.List;

public class SpreadView extends View {
    private Paint centerPaint; //中心圆paint
    private Paint paint; //图片白框
    private int radius = 100; //中心圆半径
    private Paint spreadPaint; //扩散圆paint
    private float centerX;//圆心x
    private float centerY;//圆心y
    private int distance = 1; //每次圆递增间距
    private int maxRadius = 80; //最大圆半径
    private int delayMilliseconds = 30;//扩散延迟间隔,越大扩散越慢
    private List<Integer> spreadRadius = new ArrayList<>();//扩散圆层级数,元素为扩散的距离
    private List<Integer> alphas = new ArrayList<>();//对应每层圆的透明度
    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.a_195092));
        //渐变的颜色
        int spreadColor = a.getColor(R.styleable.SpreadView_spread_spread_color, ContextCompat.getColor(context, R.color.a_496696));
        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);
        //白色边框
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setColor(Color.WHITE);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //圆心位置
        centerX = w / 2;
        centerY = h / 2;
    }
    @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);
        // 获取资源流

        Resources rec = getResources();
        BitmapDrawable bitmapDrawable = (BitmapDrawable) rec.getDrawable(R.drawable.img);
        Bitmap bitmap = bitmapDrawable.getBitmap();
//        canvas.drawBitmap(bitmap,centerX-(bitmap.getWidth()/2),centerY-(bitmap.getHeight()/2),centerPaint);
        //TODO 可以在中间圆绘制文字或者图片


        //获得图片的宽度
        int width=bitmap.getWidth();
        //获得图片的高度
        int height=bitmap.getHeight();
        //短的二分之一作为半径
        int radius=height>width?width/2:height/2;

        //重新定义的一个画布,这一步很关键
        Paint mPaint = new Paint();
        //抗锯齿
        mPaint.setAntiAlias(true);
//        Bitmap bitmap1 = Bitmap.createBitmap(width,height,
//                Bitmap.Config.ARGB_8888);
//        Canvas bitmapCanvas = new Canvas(bitmap1);
//        super.onDraw(bitmapCanvas);

        //圆形的框
        Bitmap cB = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        Canvas cCanv = new Canvas(cB);
        //在控件中间画一个
        cCanv.drawCircle(width/ 2, height/ 2, radius,
                mPaint);
        canvas.drawBitmap(bitmap, centerX-(bitmap.getWidth()/2),centerY-(bitmap.getHeight()/2), mPaint);
        //dst是后画的图形
        mPaint.setXfermode(new PorterDuffXfermode(
                PorterDuff.Mode.DST_IN));
        //一定要用之前的画布,不然会出现边角是黑色
        cCanv.drawBitmap(cB, centerX-(bitmap.getWidth()/2),centerY-(bitmap.getHeight()/2), mPaint);
        //给图形加边框
        canvas.drawCircle(centerX, centerY, radius,
                paint);
        //延迟更新,达到扩散视觉差效果
        postInvalidateDelayed(delayMilliseconds);
    }
}
<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>

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39389024/article/details/123200480

智能推荐

【英语学习】【WOTD】scavenger 释义/词源/示例_scavenge词源-程序员宅基地

文章浏览阅读1.5k次。【英语学习】【WOTD】scavenger 释义/词源/示例文章目录Podcastscavenger *n.* [SKAV-un-jer]DefinitionDid You Know?ExamplesPodcastscavenger podcastscavenger n. [SKAV-un-jer]拾荒者,食腐动物,清除剂Definition1 chiefly British: a ..._scavenge词源

mediasoup基本介绍及Ubuntu/Docker环境下部署mediasoup-程序员宅基地

文章浏览阅读2.3k次。mediasoup基本介绍Ubuntu环境mediasoup-demo安装部署Docker环境mediasoup-demo安装部署_mediasoup

Spring全家桶,永远滴神!-程序员宅基地

文章浏览阅读256次。对于Java工程师来说,几乎没有没听过大名鼎鼎的Spring框架的,Spring框架早已成为了Java后端开发事实上的行业标准,可以说,是Spring成就了Java,Spring也成为Ja..._玩转spring全家桶

微信小程序 - 根据后端返回的唯一 ID / code,生成 “唯一“ 的推荐码、邀请码、订单号、加密路由、一串英文+数字长字符等 (支持反序列化原 ID 解码,逆向得出 ID 二者互转)wechat_小程序 唯一编号生成-程序员宅基地

文章浏览阅读2.1k次,点赞3次,收藏6次。微信小程序Wechat - 公众号纯前端根据后端返回的唯一 ID / code,生成 "唯一" 的推荐码、邀请码、订单号、加密路由、一串英文+数字长字符优惠码 固定长度等 (支持反序列化原 ID 解码,逆向得出 ID 二者互转)id 生成唯一邀请码id生成唯一邀请码及解码转成idJS 根据id生成一串邀请码并逆向可得到id code uid,当您不想向用户公开数据库 ID 时使用它,不想把路由上的code展示出来有什么办法根据用户id生成一个唯一邀请码唯一加密字符串。UNIAPP uniapp最优秀的教程J_小程序 唯一编号生成

python opencv破解滑动验证码之获取缺口位置_python获得一张有缺口的图片和需要验证的小图,两张图片进行二极化以及归一化,确定-程序员宅基地

文章浏览阅读2.4k次,点赞3次,收藏18次。破解滑块验证码的思路主要有2种:一张完整的背景图和一张有缺口的图片的场景,解决思路:两张图片同一个坐标位置进行像素上的一一对比,找出不一样的坐标。 一张有缺口的图片和需要验证的小图,解决思路:1.两张图片进行二极化以及归一化,确定小图在图片中间的坐标。这种办法我没有验证通过,可以参考这里。2.通过opencv获得缺口位置 之后就要使用初中物理知识了,使用先加速后减速模仿人手动拖动通过opencv获得图片的缺口位置#coding=utf-8import cv2import numpy as_python获得一张有缺口的图片和需要验证的小图,两张图片进行二极化以及归一化,确定

Qt制作局域网即时通讯软件_局域网内语音通话qt-程序员宅基地

文章浏览阅读5.5k次,点赞31次,收藏86次。Qt制作局域网即时通讯软件 利用Qt制作的局域网即时通信软件,可实现文本信息、表情包、图片、文档等的传输功能。界面风格模仿的Tim,所以本软件取名为Timi,tim的mini版本。登录界面:使用之前做的登录界面,后续修改。原因是没找到好的素材(不会美工),有会美工愿意提供素材的请联系。 文本信息发送:气泡效n果,文本信揭秘那息可自动换行,并且文本信息可选择/可复制。 发送..._局域网内语音通话qt

随便推点

后缀自动机(SAM) 学习笔记-程序员宅基地

文章浏览阅读299次。后缀自动机(SAM) 学习笔记很久以前学过SAM,现在又忘了。学习资料后缀自动机感性理解史上最通俗的后缀自动机详解后缀自动机 (SAM)SAM如果我们把一个长度为 nnn 的串 SSS 的所有后缀放入同一个 trie 中,并标记结束位置end,可以得到一个时间、空间均为 O(n2)\mathcal O(n^2)O(n2) 的(假)后缀树。它具有以下几个性质:从根到任意 end 是一个后缀,从根到任意节点是一个子串。本质不同的子串个数就是状态(节点)个数。但是它的时空太大,不满足我们

Python-函数式编程(高阶函数、匿名函数、返回函数、装饰器)_python高阶函数-程序员宅基地

文章浏览阅读1.1w次。上篇文章思考题Python-函数基础总结与内置函数1.def plus(*args): return sum(args)print(plus(1, 2, 3))print(plus(2, 4, 6, 8, 10))结果:6302.def power(x=2, n): return x ** n结果: def power(x=2, n): ^SyntaxError: non-default ar..._python高阶函数

有向无环图拓扑排序(python实现)_python 有向无环图 拓扑排序-程序员宅基地

文章浏览阅读1.1k次。算法7-12:有向无环图的拓扑排序时间限制: 1 Sec 内存限制: 32 MB题目描述由某个集合上的一个偏序得到该集合上的一个全序,这个操作被称为拓扑排序。偏序和全序的定义分别如下:若集合X上的关系R是自反的、反对称的和传递的,则称R是集合X上的偏序关系。设R是集合X上的偏序,如果对每个x,y∈X必有xRy或yRx,则称R是集合X上的全序关系。由偏序定义得到拓扑有序的操作便是拓扑排序。拓扑排序的流程如下: 在有向图中选一个没有前驱的顶点并且输出之; 从图中删除该顶点和所有_python 有向无环图 拓扑排序

黑马程序员_笔迹二_关于IO流_要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。-程序员宅基地

文章浏览阅读376次。----------android培训、java培训期待与您交流! ---------- IO(Input Output)流--->IO流用来处理设备之间的数据传输--->java对数据的操作时通过流的方式--->Java用于操作流的对象都在IO包中--->流按操作数据分为2种:字节流和字符流--->流按流向分:输入流,输出流 IO流常用基类字节流的抽象_要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。

阿里云天池大赛赛题解析——机器学习篇 | 留言赠书-程序员宅基地

文章浏览阅读6k次。国内第一本针对竞赛实操的图书:《阿里云天池大赛赛题解析——机器学习篇》,正式发售。阿里云天池7年200多场数据大赛精华提取录为什么写这本书七年前,天池团队的几名创始成员带着“让全世界没有..._阿里云天池大赛赛题解析_机器学习篇

委外订单_ERP软件教程:金蝶ERP的委外加工业务流程(一)-程序员宅基地

文章浏览阅读6.3k次。ERP软件教程:金蝶ERP的委外加工业务流程关注我,我将定期分享更多的ERP解决方案转发关注并私信我,了解更多的解决方案及操作方法哦欢迎大家随时咨询关于金蝶ERP的任何问题!一、应用软件版本:金蝶KIS旗舰版6.0二、应用场景:委外加工业务,是指原料或半成品的委外加工处理,通常是企业提供原材料或半成品给加工商,加工商自行采购一些辅料或材料加工成半成品或产品,企业外发材料及接收委外加工品均需要通过仓..._金蝶系统委外加工操作流程