android canvas 转bitmap_Android 雪花飘落动画效果 自定义View

2023-11-15

在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天、每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不妨来瞅瞅码农的轨迹。

本文章实现的效果如下图所示:

50f43de35b2a760141e23a8ac46308a0.gif

1 首先是雪花的定义

用来保存雪花的一些基本属性

public class BobbleBean {  //位置  Point postion;  //初始位置  Point origin;  //颜色  int color;  //运动的速度  int speed;  //半径  float radius;}
2 自定义 View 创建

然后我们创建一个自定义 View 用来绘制雪花效果,在这个自定义View的构造函数中创建一个画笔,同时创建一个保存雪花的集合:

public class CustomSnowView extends View {  public CustomSnowView(Context context) {    this(context, null);  }    public CustomSnowView(Context context, @Nullable AttributeSet attrs) {    this(context, attrs, 0);  }      //画笔  Paint mPaint;    //保存点的集合  List mBobbleBeanList;    public CustomSnowView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);        mPaint = new Paint();        mBobbleBeanList = new ArrayList<>();  }}
3 绘制

绘制讲究三步

  • View的测量——onMeasure()

  • View的位置确定——onLayout()

  • View的绘制——onDraw()

3.1 第一步就是测量

通过测量要得出当前画布的精确尺寸

  //第一步测量  //默认的View大小  private int mDefaultWidth = dp2px(100);  private int mDefaultHeight = dp2px(100);    //测量过后的View 的大小  也就是画布的大小  private int mMeasureWidth = 0;  private int mMeasureHeight = 0;    @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //获取测量计算相关内容    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);    int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);        if (widthSpecMode == MeasureSpec.EXACTLY) {      //当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小      mMeasureWidth = widthSpecSize;    } else {      //指定默认大小      mMeasureWidth = mDefaultWidth;      if (widthSpecMode == MeasureSpec.AT_MOST) {        mMeasureWidth = Math.min(mMeasureWidth, widthSpecSize);      }    }        //测量计算View的高    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);    int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);    if (heightSpecMode == MeasureSpec.EXACTLY) {      //当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小      mMeasureHeight = heightSpecSize;    } else {      //指定默认大小      mMeasureHeight = mDefaultHeight;      if (heightSpecMode == MeasureSpec.AT_MOST) {        mMeasureHeight = Math.min(mMeasureHeight, heightSpecSize);      }    }    mMeasureHeight = mMeasureHeight - getPaddingBottom() - getPaddingTop();    mMeasureWidth = mMeasureWidth - getPaddingLeft() - getPaddingBottom();    //重新测量    setMeasuredDimension(mMeasureWidth, mMeasureHeight);  }
  //一个 dp 转 像素的计算  private int dp2px(int dp) {    float density = getContext().getResources().getDisplayMetrics().density;    return (int) (dp * density + 0.5f);  }
3.2 第二步就是 排版

当然这个功能主要用于 ViewGroup 中有多个 View时,在这里我们来根据画布的尺寸来随机生成雪花点的坐标信息

    //这里面创建 点  Random mRandom = new Random();    @Override  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {    super.onLayout(changed, left, top, right, bottom);        for (int i = 0; i < mMeasureWidth / 3; i++) {            BobbleBean lBobbleBean = new BobbleBean();            //生成位置信息  随机      //取值范围是 0 ~ mMeasureWidth      int x = mRandom.nextInt(mMeasureWidth);      int y = mRandom.nextInt(mMeasureHeight);            //绘制使用的位置      lBobbleBean.postion = new Point(x, y);      //重置的位置      lBobbleBean.origin = new Point(x, 0);      //随机的半径  1 ~ 4      lBobbleBean.radius = mRandom.nextFloat() * 3 + dp2px(1);      //随机的速度  3 ~ 6      lBobbleBean.speed = 1 + mRandom.nextInt(3);      //随机透明度的白色      lBobbleBean.color = ColorUtil.randomWhiteColor();      mBobbleBeanList.add(lBobbleBean);    }      }
3.3 第三步就是绘制

循环绘制,每次绘制时就将雪花的 纵坐标添加偏移量 就出现了向下落的动画效果

  @Override  protected void onDraw(Canvas canvas) {    super.onDraw(canvas);        //绘制时重新计算位置    for (BobbleBean lBobbleBean : mBobbleBeanList) {            Point lPostion = lBobbleBean.postion;      //在竖直方向上增加偏移      lPostion.y+=lBobbleBean.speed;            //在 x 轴方向上再微微偏移一点      float randValue = mRandom.nextFloat() *2 -0.5f;      lPostion.x+=randValue;            //边界控制      if(lPostion.y>mMeasureHeight){        lPostion.y = 0;      }    }        //先将这些点全部绘制出来        for (BobbleBean lBobbleBean : mBobbleBeanList) {      //修改画笔的颜色      mPaint.setColor(lBobbleBean.color);      //绘制      // 参数一 二 圆点位置      // 参数 三 半径      // 参数 四 画笔      canvas.drawCircle(lBobbleBean.postion.x, lBobbleBean.postion.y, lBobbleBean.radius, mPaint);    }        //循环刷新 10 毫秒刷新一次    postInvalidateDelayed(10L);      }
4 第四步就是使用

在布局文件中引用这个自定义View

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#000000"    tools:context=".MainActivity">    <ImageView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:scaleType="fitXY"        android:src="@mipmap/bg_snow" />    <com.studyyoun.demo.CustomSnowView        android:layout_width="match_parent"        android:layout_height="match_parent" />FrameLayout>

631552422d04a9f59881d7f98802f59d.png

不局限于思维,不局限语言限制,才是编程的最高境界。

以小编的性格,肯定是要录制一套视频的,随后会上传

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android canvas 转bitmap_Android 雪花飘落动画效果 自定义View 的相关文章

  • Spring Cloud(八):使用Spring Cloud Bus来实现配置动态更新

    使用Spring Cloud Config我们能实现服务配置的集中化管理 在服务启动时从Config Server获取需要的配置属性 但如果在服务运行过程中 我们需要将某个配置属性进行修改 比如将验证码的失效时间从五分钟调整为十分钟 如何将
  • 使用VS Code进行Vue模板编程的设置方法

    Vue js是一种流行的JavaScript框架 用于构建前端应用程序 在VS Code中进行Vue模板编程时 可以通过一些扩展和配置来提高开发效率 本文将介绍如何设置VS Code以优化Vue模板编程体验 安装Vue扩展 首先 我们需要安
  • vscode 统计代码行数的插件

    1 安装插件 VS Code Counter 2 安装好之后 shift ctrl p 调出命令行 选择合适的命令直接统计 一般点击 Count lines in directory 然后确认要统计的目录即可 3 会以统计时间生成统计文件夹
  • VS Code + Markdown Preview Enhanced 出现 mermaid预览流程图看不见线条问题的解决方案

    VS Code mermaid预览流程图看不见线条问题的解决方案 使用mermaid插件可以在Markdown文档中插入漂亮的流程图 但是VS code安装上Markdown Preview Enhanced插件之后 看到的却是这样的效果
  • Java之集合的排序方式(Comparable和Comparator的基本使用以及区别)

    文章目录 一 Comparable接口 1 代码示例 2 运行结果 3 案例分析 二 Comparator接口 1 代码示例 2 运行结果 3 案例分析 三 Comparable和Comparator对比 1 接口位置 2 实现方式 3 排
  • SpringBoot + Mybatis 多模块( module )项目搭建教程

    作者 枫本非凡 www cnblogs com orzlin p 9717399 html 一 前言 最近公司项目准备开始重构 框架选定为SpringBoot Mybatis 本篇主要记录了在IDEA中搭建SpringBoot多模块项目的过
  • 8k Byte , 8bit的ROM存储器,其地址线和数据线各需要多少根?

    总共容量为810248bits 2 16bits 因此其地址线需要16根 因为是8bit的ROM存储器 因此数据线需要8根
  • 使用ggplot2包在R语言中抑制数据轴上的科学计数法

    使用ggplot2包在R语言中抑制数据轴上的科学计数法 在数据可视化领域 ggplot2是R语言中最流行和强大的包之一 它提供了丰富的功能和灵活性 使我们能够创建出美观 清晰的图形来展示数据 其中一个常见的问题是 当我们使用ggplot2绘
  • 【自然语言处理】隐马尔可夫模型【Ⅵ】精度问题

    有任何的书写错误 排版错误 概念错误等 希望大家包含指正 由于字数限制 分成六篇博客 自然语言处理 隐马尔可夫模型 马尔可夫模型 自然语言处理 隐马尔可夫模型 隐马尔科夫模型概述 自然语言处理 隐马尔可夫模型 估计问题 自然语言处理 隐马尔
  • 非递减排列和非递增排列的定义

    递增排列 1 2 3 4 5 6 7 8 递减排列 8 7 6 5 4 3 2 1 非递减排列 1 2 3 4 5 6 6 7 8 8 非递增排列 9 8 8 7 6 5 2 2 1
  • 小白学python-数据清洗

    数据清洗 赔率 公路堵车模型的概念及应用 主成分分析PCA 新的的特征组合 车辆数据描述 one hot编码会使特征值大量增加 维度变高视情况而定 Logistic回归 AUC 曲线下的面积 求取素数以及赔率的代码 import opera
  • web service概念、架构及相关知识

    一 WebService的定义 WebService有好几种定义 W3C组织对其定义 WebService是一个软件系统 为了支持跨网络的机器间互操作交互而设计 WebService通常被定义为一组模块化的API 我们可以通过网络进行调用
  • 太原理工大学19年Java试题复习笔计

    19年Java复习题 1 为使一个名为Example的public类成功编译 需至少满足以下哪个条件 2 0分 A Example类中必须定义一个正确的main函数 B Example类中必须定义在 Example java源文件中 C E
  • sklearn 神经网络

    sklearn 神经网络 url https blog csdn net luanpeng825485697 article details 79064657 url sklearn 神经网络 多层感知器的优点 可以学习得到非线性模型 使用
  • 雷军发布会刚结束,就能写出上万字原创文章!

    前言 看完雷军演讲会之后你有没有看到过很多文章 成千上万个字的原创文章 瞬间就出现了 这是一个一个字敲的吗 当然不是 是AI 话不多说直接上教程 把雷军的演讲整理到笔记中 可以是md格式 word格式等等 复制粘贴即可 打开网站 smart
  • vmware workstation14连网

    记录一下手残的过程 1 选择NAT形式的连接 2 在桌面的右上角有个圆圈 右击这个图标 会显示一个有线连接 默认是关闭的 3 所以设置成连接状态 4 右击有线连接 进行网络配置 5 所有都配置成自动获取
  • MybatisPlus多表连接查询

    mybatis plus作为mybatis的增强工具 它的出现极大的简化了开发中的数据库操作 但是长久以来 它的联表查询能力一直被大家所诟病 一旦遇到left join或right join的左右连接 你还是得老老实实的打开xml文件 手写
  • mybatis与数据库连接过程

    菜鸟发文 请大神多多指导 1 准被一个maven项目 2 先导入jar包 3 配置mybatis核心文件 4 把连接数据库的配置项抽离出来 5 编写实体类 6 编写接口 7 编写mapper映射文件 8 把相同SQL session 方法抽
  • TCP三次握手-backlog队列问题

    TCP三次握手 backlog队列问题 md 概述 之前有同事做压力测试时 发现无论如何都无法突破128并发的问题 经排查发现该服务器ACCEPT QUEUE队列都为128 限制了网络的并发 TCP三次握手 Linux内核协议栈为一个TCP

随机推荐

  • 初识-常见浏览器兼容性问题与解决方案

    浏览器兼容问题一 不同浏览器的标签默认的外补丁和内补丁不同 问题症状 随便写几个标签 不加样式控制的情况下 各自的margin 和padding差异较大 碰到频率 100 解决方案 CSS里 margin 0 padding 0 备注 这个
  • 前后端利用accessToken与refreshToken无感刷新

    项目初衷 以jwt 由header payload和signature组成 为例 用户登录成功 后端返回accessToken 前端保存 请求接口携带 一切都是水到渠成的 可是在acessToken失效时 你正好请求一次接口 接口就挂了 可
  • SpringBoot集成ShedLock分布式定时任务

    文章目录 前言 一 背景 二 ShedLock是什么 三 落地实现 1 1 引入依赖包 1 2 配置数据库连接信息 1 3 创建Mysql数据表 1 4 配置LockProvider 1 5 创建定时Job 四 结果分析 前言 一 背景 在
  • 【性能测试】Jmeter —— jmeter计数器

    jmeter计数器 如果需要引用的数据量较大 且要求不能重复或者需要递增 那么可以使用计数器来实现 如 新增功能 要求名称不能重复 1 新增计数器 计数器 允许用户创建一个在线程组之内都可以被引用的计数器 计数器允许用户配置一个起点 一个最
  • 《Go语言在微服务中的崛起:为什么Go是下一个后端之星?》

    博主猫头虎 带您进入 Golang 语言的新世界 博客首页 猫头虎的博客 面试题大全专栏 文章图文并茂 生动形象 简单易学 欢迎大家来踩踩 IDEA开发秘籍专栏 学会IDEA常用操作 工作效率翻倍 100天精通Golang 基础入门篇 学会
  • c语言 常量表达式,Constant expressions(常量表达)

    几种表达式被称为常量表达式 预处理器常量表达式 if 或 elif 后面的表达式必须扩展为 除赋值 增量 减量 函数调用或逗号之外的其他操作符 其参数是预处理常量表达式 整数常量 字符常量 特殊的预处理器操作员 defined 当在 if表
  • 面试题 : Top-k问题

    目录 简介 题目 示例 提示 开始解题 1 思路 2 解题代码 3 时间复杂度 4 运行结果 编辑 目前问题 真正的解法 1 以找前K个最大的元素为例 2 代码执行过程 时间复杂度的计算 3 画图演示代码执行过程 4 解题代码 两种解法的比
  • webpack3 配置详解

    今天详细的学习了webpack3 下面贴出我的主要配置代码给后来人一些参考 Created by shanpengfei051 on 2018 1 3 const path require path const uglify require
  • H264编码原理(I帧B帧P帧)

    I帧B帧P帧 编码帧的分类 I帧 intraframe frame 关键帧 采用帧内压缩技术 IDR帧属于I帧 每个GOP组中第一帧肯定是I帧 而且还是一种特殊的I帧 也可以称为IDR帧 一个GOP中可能有很多I帧 但是只有一个IDR帧 如
  • MySQL 行转列 列转行

    转载 mysql 行转列 列转行 行转列 准备数据 CREATE TABLE tb score id INT 11 NOT NULL auto increment userid VARCHAR 20 NOT NULL COMMENT 用户i
  • centos7安装apache

    centos7安装apache 第一步 检查是否有旧版本的apache 有就卸载 rpm qa grep httpd 因为我没有 就没有卸载的动作 第二步 安装apache yum install httpd 默认yes 可以添加参数 y
  • Linux环境下安装ssh2模块

    环境 Linux环境 Centos or RedHat 1 确认环境已安装php 5 rpm qa grep php 5 php 5 3 3 48 el6 8 x86 64 2 安装ssh2所依赖的rpm包如下图灰色部分显示 安装顺序可以按
  • Less-22 Cookie Injection- Error Based- Double Quotes - string (基于错误的双引号字符型Cookie注入)

    这关和上一关类似 只不过把单引号注入改成了双引号 看题目 尝试取消报错 成功 发现and后面的条件真假回显会不同 所以我们同样有很多的方法去注入 详见第二十关 这里我们使用联合查询 其他方法自行进行解码 很简单 结束
  • cocos2d-x 物理世界与spine骨骼的运用

    Head ifndef HELLOWORLD SCENE H define HELLOWORLD SCENE H include cocos2d h include spine spine h include E tesetspine co
  • 第四部分、JEECG-BOOT 微服部署文档

    文章目录 第四部分 微服部署文档 微服务部署 一 制作各个服务JAR包 二 配置host 三 初始化Mysql数据库 四 启动微服务各个组件 五 前端部署 六 其他软件安装 第四部分 微服部署文档 微服务部署 后端服务通过JAR方式运行 支
  • JAVA中的比较器

    引出 传统的对象之间是一般都是 或者 看对象是否为同一个 而没有存在 gt 或者 lt 类似的 但有的时候我们需要根据 对象的某一个属性进行排序 怎么办呢 这个时候就引出来 比较器了 主要是两个接口 Comparable和Comparato
  • python 获取指定文件夹里面的图片文件的信息

    import time import exifread import os 切换到图片文件夹 由于我的这个文件夹里全部是图片文件所以无需判断直接遍历 os chdir news aa 遍历所有图片文件 for x y z in os wal
  • 简单的动态规划——装箱问题

    装箱问题 告诉你箱子的容积为多少 告诉你有N件物品和每一件物品的体积 问如何选择物品才能令箱子的剩余容积最小 搜索递归 include
  • spring动态修改bean

    spring动态修改bean RequestMapping ok public Object test2 ApplicationContext applicationContext SpringContextUtil getApplicat
  • android canvas 转bitmap_Android 雪花飘落动画效果 自定义View

    在码农的世界里 优美的应用体验 来源于程序员对细节的处理以及自我要求的境界 年轻人也是忙忙碌碌的码农中一员 每天 每周 都会留下一些脚印 就是这些创作的内容 有一种执着 就是不知为什么 如果你迷茫 不妨来瞅瞅码农的轨迹 本文章实现的效果如下