首页 > 其他分享 >Android水波纹效果

Android水波纹效果

时间:2024-12-09 10:30:41浏览次数:5  
标签:水波纹 spreadRadius SpreadView 效果 int private styleable context Android

Android水波纹效果

需要到水波纹效果的场景还蛮少的。万一刚好你需要呢

一、思路:

自定义组件SpreadView

二、效果图:

在这里插入图片描述
看视频更直观点:

<iframe allowfullscreen="true" data-mediaembed="bilibili" frameborder="0" id="QSV47dH9-1733711079169" src="https://player.bilibili.com/player.html?aid=977473903"></iframe>

Android轮子分享-水波纹效果

三、关键代码:
public class SpreadView extends View {

    private Paint centerPaint; //中心圆paint
    private int radius = 100; //中心圆半径 px
    private Paint spreadPaint; //扩散圆paint
    private float centerX;//圆心x
    private float centerY;//圆心y
    private int distance = 5; //每次圆递增间距 px
    private int maxRadius; //扩散波纹圆最大半径 px
    private int radiusDifference = 120; // 二个扩散圈之间距离差
    private boolean isNeedCenter = false; // 是否需要绘画中心圆
    private int delayMilliseconds = 25;//扩散延迟间隔,毫秒,越大扩散越慢
    private List<Integer> spreadRadius = new ArrayList<>();//扩散圆层级数,元素为扩散的距离
    private List<Integer> alphas = new ArrayList<>();//对应每层圆的透明度
    private int alphaReduce ; //每次透明度减少量
    private int spreadStartTransparency = 255; // 扩散波纹最开始的透明度,最大255为完全不透明

    public SpreadView(Context context) {
        this(context, null, 0);
    }
    public SpreadView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public SpreadView(Context context, 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, getScreenWidth(getContext(),false)/2);
        isNeedCenter = a.getBoolean(R.styleable.SpreadView_is_need_center, isNeedCenter);
        int centerColor = a.getColor(R.styleable.SpreadView_spread_center_color, ContextCompat.getColor(context, R.color.c_main));
        int spreadColor = a.getColor(R.styleable.SpreadView_spread_spread_color, ContextCompat.getColor(context, R.color.white));
        distance = a.getInt(R.styleable.SpreadView_spread_distance, distance);
        spreadStartTransparency = a.getInt(R.styleable.SpreadView_spread_start_transparency, spreadStartTransparency);
        a.recycle();
        if(isNeedCenter){
            centerPaint = new Paint();
            centerPaint.setColor(centerColor);
            centerPaint.setAntiAlias(true);
        }
        alphas.add(spreadStartTransparency);
        spreadRadius.add(0);
        spreadPaint = new Paint();
        spreadPaint.setAntiAlias(true);
        spreadPaint.setAlpha(spreadStartTransparency);
        spreadPaint.setColor(spreadColor);
    }

    @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);
        if(alphaReduce == 0){
            int num = (maxRadius - radius)/distance;
            alphaReduce = num > 1 ? Math.max((spreadStartTransparency / (num - 1)), 1) : spreadStartTransparency;
        }
        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) {
                alpha = alpha - alphaReduce > 0 ? alpha - alphaReduce : 1;
                alphas.set(i, alpha);
                spreadRadius.set(i, width + distance);
            }
        }
        //当上一个扩散圆增加的半径达到此值时添加新扩散圆
        if (spreadRadius.get(spreadRadius.size() - 1) > radiusDifference) {
            spreadRadius.add(0);
            alphas.add(spreadStartTransparency);
        }
        //删除最先绘制的圆,即最外层的圆
        if (alphas.get(0) == 1) {
            alphas.remove(0);
            spreadRadius.remove(0);
        }

        //中间的圆
        if(isNeedCenter){
            canvas.drawCircle(centerX, centerY, radius, centerPaint);
        }
四、项目demo源码结构图:

在这里插入图片描述

有问题或者需要完整源码demo的私信我,我每天都看私信的

标签:水波纹,spreadRadius,SpreadView,效果,int,private,styleable,context,Android
From: https://blog.csdn.net/u010074743/article/details/144339912

相关文章

  • .NET for Android/iOS应用的如何在各自的系统运行
    1..NETforAndroid上的运行机制Android应用使用Mono运行时或.NET运行时在Android设备上执行。具体过程如下:编译过程:C#代码编写:开发者使用C#编写业务逻辑代码。编译为IL:C#代码通过Roslyn编译器转换为中间语言(IL)。JIT或AOT编译:JIT(即时编译):在Androi......
  • 使用canvas画一个小球自由落体的效果
    <!DOCTYPEhtml><html><head><title>自由落体</title><style>body{margin:0;}canvas{display:block;}</style></head><body><canvasid="myCanvas"></canvas><script&g......
  • 如何在PbootCMS中优化图片上传和显示效果?
    在PbootCMS中优化图片上传和显示效果对于提升网站的用户体验和SEO效果至关重要。以下是一些具体的优化方法,帮助你更好地管理图片上传和显示:压缩和优化图片:在上传图片之前,使用专业的图片压缩工具(如TinyPNG、ImageOptim等)对图片进行压缩,减少文件大小。压缩后的图片可以更快地......
  • 深入解析 Android PMS —— APK 安装与解析全流程
    文章目录前言1.PMS的初始化1.1SystemServer启动PMS1.2PMS的入口方法main1.3PMS构造函数1.4扫描APK文件1.5权限初始化1.6提供对外服务2.APK安装机制2.1.安装请求的触发2.2APK文件解析与验证2.3签名校验2.4权限管理2.4.1权限声明2.4.2权限校验与......
  • Android 通知权限
    >>在AndroID13中引入了通知权限: android.permission.POST_NOTIFICATIONS   在AndroID13之前,可以直接通过 NotificationCenter控件来发送消息;    在AndroID13之后,需要动态申请此权限,才可以发送通知;>>动态权限申请 procedureTForm1.Button1Click(S......
  • Android 10.0 WiFi连接流程分析一
    1.前言在10.0的系统rom定制化开发中,对于wifi的定制功能也是比较多的,在关于wifi连接流程模块的分析,了解整个wifi连接流程也是非常重要的,接下来看下wifi的连接流程分析下相关功能实现2.WiFi连接流程分析一的核心类packages/apps/Settings/src/com/android/settings/wifi/Wifi......
  • Android移动开发基础——广播
    在Android开发的世界里,广播(Broadcast)是极为重要的系统级通信机制,它就像一个无形的传声筒,让不同组件之间能够灵活地收发消息,不管是系统状态的变更通知,还是应用内部的自定义事件传达,广播都能派上用场。今天,就跟着我一步步拆解一个Android广播基础项目,深入理解广播的创建、注......
  • Android移动开发基础——Handler机制
    ⼀、Handler原理在Android中,Handler是⼀个重要的⼯具,主要⽤于在不同线程之间传递消息或执⾏任务,特别是从后台线程向主线程(UI线程)发送任务。Handler的⼯作原理依赖于Looper和MessageQueue,它们共同组成了Android的消息处理机制。⼆、Handler原理概述1、线程和消息......
  • Android14 关于读写权限 (Vivo)
    按常理来讲,在相机业务,或从相册读取图片时,应该要申请读写权限,在使用Delphi12+Android14环境下,发现在申请读写权限时,申请权限内容中,这二项不需要授权?不清楚是自己处理的问题,还是规则有所变更>>申请权限>>相机申请三项权限,无论怎么操作,都只有相机权限一项返回(关于读写......
  • Android Codec2 CCodec (二八)SimpleC2Component
    在AndroidCodec2(九)组件实现分析一文中,我们了解了Codec2组件的实现框架,接下来这一章我们将深入探讨组件的实现细节。1、C2ComponentC2Component抽象了Codec2组件的控制与CallbackAPI。首先来看Callback类Listener:classListener{public:virtualvoidonWork......