对于一个自定义View来说,onMeasure只是用来计算View尺寸,onDraw()才是真正执行View的绘制,所以一般我们都需要重写onDraw()函数来绘制我们期望的UI界面,下面我以一个具体的例子探索自定义View的onDraw()的实现过程和关键点。

我们的目标是制作一个柱状图动画,View的动画启动后,会显示一排柱状图增长的画面,这种动画多用于财务类或者统计类的APP中,效果如图所示(截屏的格式转换过程导致有些变形,还好不影响演示,图中设置了反复播放,真机上只会播放一次):

1. 首先,自定义View的派生类

public class AnimatorView extends View {

private Paint mPaint;

public AnimatorView(Context context) {

super(context);

initialize();

}

public AnimatorView(Context context, AttributeSet attrs) {

super(context, attrs);

initialize();

}

public AnimatorView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

initialize();

}

protected void initialize() {

mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setStyle(Style.FILL);

}

}

注: Paint是用来绘图的画笔,可以设置其样式、画面的粗细、填充模式、颜色等等。

2. 定义待绘制的图形数据

待绘制的图形数据一般是在程序中动态给出的,这里为了演示,直接定义好:

public class AnimatorView extends View {

private static final int RECT_WIDTH = 60; //每个矩形块的宽度

private static final int RECT_DISTANCE = 40; //矩形块之间的间距

private static final int TOTAL_PAINT_TIMES = 100; //控制绘制速度,分100次完成绘制

//待绘制的矩形块矩阵,left为高度,right为颜色

private static final int[][] RECT_ARRAY = {

{380,Color.GRAY},

{600,Color.YELLOW},

{200,Color.GREEN},

{450,Color.RED},

{300,Color.BLUE}

};

private int mPaintTimes = 0; //当前已经绘制的次数

}

3. 重载onDraw()函数,实现绘制

public class AnimatorView extends View {

@Override

protected void onDraw(Canvas canvas) {

mPaintTimes++;

for( int i=0; i

mPaint.setColor(RECT_ARRAY[i][1]);

int paintXPos = i*(RECT_WIDTH+RECT_DISTANCE) + RECT_DISTANCE;

int paintYPos = RECT_ARRAY[i][0]/TOTAL_PAINT_TIMES*mPaintTimes;

canvas.drawRect(paintXPos, getHeight(), paintXPos+RECT_WIDTH,getHeight()-paintYPos, mPaint);

}

if( mPaintTimes < TOTAL_PAINT_TIMES ) {

invalidate(); //实现动画的关键点

}

}

}

(1)onDraw()函数一般由系统布局管理器来调用,在View第一次加载的时候会调用一次,或者在系统认为需要重绘的时候也会被调用。当然,你也可以在程序中手动触发该View的重绘,通过调用View的invalidate()函数或者postInvalidate()函数即可,前者用于UI线程,后者用于非UI线程。

(2)onDraw()的参数Canvas我们可以理解成系统提供给我们的一块内存区域,所有的绘制都是在这块内存中进行的,绘制完成后系统会显示到屏幕中去。该Canvas对象提供了各种绘制点、线、矩形、圆、位图的方法,基本可以满足各种绘制要求。

(3) drawRect函数需要提供四个坐标,其中,前两个参数代表是被绘制矩形的起始点坐标,后两个参数则是相对于起点的斜对角坐标,注意,原点坐标(0,0)在屏幕的左上角。

(4) 注意,onDraw()每次被调用的时候,原来画布中的内容会被清空。

(5) 本示例中,矩形高度每次增加Height/TOTAL_PAINT_TIMES,宽度不变。

4. Activity中测试该View

public class MainActivity extends Activity {

private AnimatorView mAnimatorView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mAnimatorView = new AnimatorView(this);

setContentView(mAnimatorView);

}

}

当然,也可以把该View放到layout文件中,这里就不赘述了。

5. 小结

自定义带动画的View就介绍到这里了,关键是在于掌握onDraw()的重写和invalidate()的调用,先谢谢大家的阅读,不过你都都看到这了,不留个赞在走吗?

另外整理收集的Android一线大厂面试完整考点、资料【完整版】已更新在我的【Github】,有面试需要的朋友们可以去参考参考,如果对你有帮助,可以点个Star哦!

android伸缩动画自定义,Android干货:自定义带动画的View相关推荐

  1. 微信小程序之自定义模态弹窗(带动画)实例

    代码地址如下: http://www.demodashi.com/demo/13991.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.c ...

  2. View的进阶,自定义一款自带动画的雷达图

    /   今日科技快讯   / 近日工信部发放四张5G商用牌照,中国联通.中国移动.中国电信和中国广播电视网络有限公司各得到一张牌照.中国的5G商用元年正式开启.5G牌照的发放,将推升产业链的成熟.加快 ...

  3. 万字长文!View的进阶,自定义一款自带动画的雷达图

    点击上方 "程序员小乐"关注, 星标或置顶一起成长 关注订阅号「程序员小乐」,收看更多精彩内容 每日英文 You can't change the past, but you ca ...

  4. Qt 自定义悬浮窗(带动画,类似QQ拼音输入法)

    1.运行效果 实现功能: 1.可拖动. 2.可显示,可隐藏 . 3.悬浮在主界面上面. 4.带动画. 2.ui界面  3.源码 //FloatingWindow.h #pragma once#incl ...

  5. ae制h5文字动画_绝对干货!H5动画制作方法全揭秘

    原标题:绝对干货!H5动画制作方法全揭秘 近年来,H5页面火爆整个移动互联网,这些页面的炫酷展现,都离不开动效设计和制作,而动效设计和制作早已成为一名合格设计师必需掌握的技能. 目前,设计师制作H5页 ...

  6. Android 自定义view画带指针带动画的上半圆弧刻度盘

    之前工作中有用到环形进度条等的,为了赶进度都是在网上找到相似的效果的然后再进行修改.一直都想自己画一个,今天就和大家一起来学习刻度盘的绘制. 先看一下截图: 效果演示请看 刻度盘演示 代码下载:Cal ...

  7. android view绘制中调用的函数,Android开发实践:自定义带动画的View

    前面两篇文章介绍了自定义View的onMeasure和onLayout原理,本文准备介绍自定义View的第三个关键部分,即onDraw()函数的重载. 对于一个自定义View来说,onMeasure只 ...

  8. android 自定义view 动画效果,Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又 ...

  9. android 数字滚动抽奖_Android TextView自定义数字滚动动画

    背景 在开发需求当中,当有总收益.总用户数等数字要显示时,为了更好的给用户提供展示效果,往往会想加入炫酷的数字滚动动画,使呆板平静的数字变得灵活起来,给人一种增值的直观感受. 简介 NumberRol ...

最新文章

  1. 基于平面几何精确且鲁棒的尺度恢复单目视觉里程计
  2. 面试题:mysql 一棵 B+ 树能存多少条数据?
  3. 如何用SendMessage模拟某一按钮的点击事件
  4. php怎么写for循环,PHP for循环的写法和示例
  5. Linux系统编程12:进程入门之进程的优先级及PR和NI如何修改进程优先级
  6. 将Entity Framework Core v5.0移至单独的项目
  7. OA并发用户数(转)
  8. *第十三周*数据结构实践项目二【验证Kruskal算法】
  9. SAS编程基础 - 数据获取与数据集操作(1)
  10. 接入华为webpush webpush总结
  11. NISP-电子邮件安全
  12. kuka机器人码垛编程网盘_KUKA机器人码垛程序怎么写(案例)
  13. 发现一个可以让程序员提神的方法
  14. gulp-tinypng-nokey [error]: xxx Too many files uploaded at once
  15. 路由器广域网接口简介
  16. audio实现歌词同步
  17. 电脑文件不小心删除了怎么恢复 ? 删除的文件如何恢复文件?
  18. A + B Proble
  19. 《中国历代政治得失》读书笔记
  20. Linux网络虚拟化基石 network namespace

热门文章

  1. pyspider 数据存储到mongoDB中
  2. mysql lost connection to server during query
  3. Maven学习(三)-----Maven本地资源库
  4. 模拟计算器进行四则运算(同等优先级)(内测第2届第3题)
  5. jQuery -gt; end方法的使用方法
  6. hdu 1002 A+B problem II
  7. mac 遇到的奇怪问题?
  8. 单点登录解决方案-CAS
  9. Linux 相关术语_002
  10. 前端框架之Vue(1)-第一个Vue实例