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

智能推荐

VS解决error C2664: “DWORD GetCurrentDirectoryW(DWORD,LPWSTR)”: 无法将参数 2 从“char [260]”转换为“LPWSTR_word[260]转换为lpwstr-程序员宅基地

文章浏览阅读4.6k次,点赞3次,收藏4次。问题:VS解决error C2664: “DWORD GetCurrentDirectoryW(DWORD,LPWSTR)”: 无法将参数 2 从“char [260]”转换为“LPWSTR环境:系统:Win10环境:VS2015 64bit问题原因:项目配置字符集选择问题错误。 解决方法:将当前项目的字符集选项改为使用多字节字符集。_word[260]转换为lpwstr

STM32常见错误_undefined symbol __set_faultmask-程序员宅基地

文章浏览阅读1.3k次。一、 在“Debug选项卡”下设置好仿真器的类型后,下载程序时却提示“No ULINK Device found.” 解决办法: Keil MDK默认使用ULINK仿真器下载程序,在“Utilities选项卡”下把编程所使用的仿真器改为相应的类型即可。 二、 编译工程时提示如下信息: main.axf: Error: L6218E: Undefined symbol _undefined symbol __set_faultmask

Python3爬取淘宝网商品数据__m_h5_tk-程序员宅基地

文章浏览阅读7.3k次,点赞8次,收藏32次。前言在这里我就不再一一介绍每个步骤的具体操作了,因为在上一次爬取今日头条数据的时候都已经讲的非常清楚了,所以在这里我只会在重点上讲述这个是这么实现的,如果想要看具体步骤请先去看我今日头条的文章内容,里面有非常详细的介绍以及是怎么找到加密js代码和api接口。Python3爬取今日头条文章视频数据,完美解决as、cp、_signature的加密方法分析淘宝网这次选择的是淘宝网热卖而不是淘宝网,二者虽然名字有不同,但是数据还是一样的,区别就在于前者把后者的所有店铺和商品的海量数据按照销售量、好评度、信誉__m_h5_tk

GWO优化LSBooST回归预测(matlab代码)-程序员宅基地

文章浏览阅读289次,点赞9次,收藏6次。这种算法的设计灵感来源于灰狼群体的捕食行为,其核心思想在于模仿灰狼社会的结构和行为模式。结果可视化:通过绘制GWO寻优过程收敛曲线、训练集、验证集和测试集的真实标签与预测标签的曲线对比图,直观地展示了模型的预测效果,便于用户理解算法和模型的性能。数据处理流程清晰:对数据进行了标准化处理,包括Zscore标准化,将数据分为训练集、验证集和测试集,有助于保证模型训练的准确性和可靠性。模块化结构:代码按照功能模块进行划分,清晰地分为数据准备、参数设置、算法处理块和结果展示等部分,提高了代码的可读性和可维护性。

【C语言/C++学习】函数(一)_c语言函数和c++函数学习方法-程序员宅基地

文章浏览阅读542次。文章目录1、引言1、引言_c语言函数和c++函数学习方法

2020 cr节目源_直播源2020-10-10-程序员宅基地

文章浏览阅读4.6k次。#EXTM3U#EXTINF:-1 ,翡翠台https://pullhls3948069e.live.126.net/live/7b23e9c43a5ae5ac5fbc5798ba287286/playlist.m3u8#EXTINF:-1 ,翡翠台http://116.199.5.52/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=...

随便推点

网络结构搜索 (NAS: Network Architecture Search)-程序员宅基地

文章浏览阅读8k次,点赞7次,收藏48次。NAS Definition基于搜索策略,并结合约束条件 (如accuracy、latency),在搜索空间内 (set of candidate operations or blocks)探索最优网络结构、或组件结构 (如detector的backbone、FPN); 高效的NAS算法,通常是Trade-off between data-driven and experience-driv..._network architecture search

运营技能:从公众号引流到小程序(关注自动回复小程序消息)_公众号回复小程序-程序员宅基地

文章浏览阅读1.3k次,点赞2次,收藏2次。文章目录引言I 从公众号引流到小程序1.1 获取小程序路径1.2 公众号自动回复小程序消息see also引言经常有小程序的朋友问我公众号是如何回复小程序消息的问题,今天就总结分享下。I 从公众号引流到小程序从公众号文章直接跳转小程序的指定路径公众号自动回复小程序消息1.1 获取小程序路径获取小程序路径的用途:从公众号文章直接跳转小程序的指定路径扫码跳转指定页面小程序链接的两种形式形式1: pages开通的格式,比如我小程序的下面这些路径,常常用于文章和聊天窗口的挑战。_公众号回复小程序

TensorFlow 可视化显示 运行过程_pycharm tensorflow 运行状态-程序员宅基地

文章浏览阅读462次。最近两天在跟着莫烦大神修炼TensorFlow,今天学到的是TensorFlow 可视化,是Tensorboard下显示的。现附上莫烦大神的代码,和本机运行的可视化结果和操作。学习视频:Tensorflow 搭建自己的神经网络 (莫烦 Python 教程)https://www.bilibili.com/video/av16001891系统环境:Win7 64位 ..._pycharm tensorflow 运行状态

C++STL中map内存彻底释放方法_c++ map 手动释放-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏46次。最近遇到一个特别占内存的需求。使用STL map/unordered_map,内存无法得到正确释放。再次响应请求,会出现内存溢出的情况。[6453149.107435] Memory cgroup out of memory: Kill process 54949 (******) score 1001 or sacrifice child[6453149.117193] Killed p..._c++ map 手动释放

Qt小例子学习75 - 把QGraphicsItem 保存到文本然后读出来显示_qt qgraphicspathitem 保存 读取saveitem-程序员宅基地

文章浏览阅读768次。Qt小例子学习75 - 把QGraphicsItem 保存到文本然后读出来显示#include "utils.h"#include <QApplication>#include <QDebug>#include <QFile>#include <QGraphicsLineItem>#include <QGraphicsScene>#include <QGraphicsView>#include <QTimer&g_qt qgraphicspathitem 保存 读取saveitem

详解十三款运维监控工具_听云 监控宝-程序员宅基地

文章浏览阅读5k次,点赞3次,收藏42次。目录一、开源工具介绍1、Zabbix2、Nagios3、Ganglia4、Grafana5、Zenoss6、Open-falcon7、Cacti8、天兔开源监控(只适用于mysql、redis、oracle)二、商用运维监控系统篇1、监控宝2、听云3、360网站服务监控4、阿里云监控5、百度云观测纵观我们部署在基础设施当中并始终保持运作的全部测量机制,监控系统无疑是重要性最高的机制之一,但它却常常遭到我们的忽视。如果能够建立起一套坚实的监控_听云 监控宝