Android开发实践:自定义带动画的View

简介:

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


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


    wKioL1P9u5zxbwpDAAF_groDb8A132.gif


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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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. 定义待绘制的图形数据


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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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()函数,实现绘制


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public  class  AnimatorView  extends  View {
 
     @Override
     protected  void  onDraw(Canvas canvas) {
 
         mPaintTimes++;
         
         for int  i= 0 ; i<RECT_ARRAY.length; 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

   

1
2
3
4
5
6
7
8
9
10
11
12
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文件中,这里就不赘述了。



本文转自 Jhuster 51CTO博客,原文链接:http://blog.51cto.com/ticktick/1545863,如需转载请自行联系原作者
相关文章
|
2天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
21 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
21天前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
50 1
|
25天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
30天前
|
调度 数据库 Android开发
构建高效Android应用:Kotlin协程的实践与优化
在Android开发领域,Kotlin以其简洁的语法和平台友好性成为了开发的首选语言。其中,Kotlin协程作为处理异步任务的强大工具,它通过提供轻量级的线程管理机制,使得开发者能够在不阻塞主线程的情况下执行后台任务,从而提升应用性能和用户体验。本文将深入探讨Kotlin协程的核心概念,并通过实例演示如何在实际的Android应用中有效地使用协程进行网络请求、数据库操作以及UI的流畅更新。同时,我们还将讨论协程的调试技巧和常见问题的解决方法,以帮助开发者避免常见的陷阱,构建更加健壮和高效的Android应用。
36 4
|
1月前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin协程的实践之路
【2月更文挑战第31天】 在移动开发领域,性能优化和流畅的用户体验一直是开发者追求的目标。随着Kotlin语言的流行,其异步编程解决方案——协程(Coroutines),为Android应用带来了革命性的并发处理能力。本文将深入探讨Kotlin协程的核心概念、设计原理以及在Android应用中的实际应用案例,旨在帮助开发者掌握这一强大的工具,从而提升应用的性能和响应能力。
|
1月前
|
移动开发 调度 Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【2月更文挑战第30天】 在移动开发领域,尤其是针对Android平台,性能优化和应用流畅度始终是开发者关注的重点。近年来,Kotlin语言凭借其简洁性和功能性成为Android开发的热门选择。其中,Kotlin协程作为一种轻量级的线程管理解决方案,为异步编程提供了强大支持,使得编写非阻塞性代码变得更加容易。本文将深入分析Kotlin协程的核心优势,并通过实际案例展示如何有效利用协程提升Android应用的性能和响应速度。
|
22天前
|
Java Android开发 开发者
构建高效Android应用:Kotlin协程的实践与优化
在响应式编程范式日益盛行的今天,Kotlin协程作为一种轻量级的线程管理解决方案,为Android开发带来了性能和效率的双重提升。本文旨在探讨Kotlin协程的核心概念、实践方法及其在Android应用中的优化策略,帮助开发者构建更加流畅和高效的应用程序。通过深入分析协程的原理与应用场景,结合实际案例,本文将指导读者如何优雅地解决异步任务处理,避免阻塞UI线程,从而优化用户体验。
|
16天前
|
移动开发 API Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【4月更文挑战第7天】 在移动开发领域,性能优化和应用响应性的提升一直是开发者追求的目标。近年来,Kotlin语言因其简洁性和功能性在Android社区中受到青睐,特别是其对协程(Coroutines)的支持,为编写异步代码和处理并发任务提供了一种更加优雅的解决方案。本文将探讨Kotlin协程在Android开发中的应用,揭示其在提高应用性能和简化代码结构方面的潜在优势,并展示如何在实际项目中实现和优化协程。
|
16天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。
|
18天前
|
监控 算法 Android开发
安卓应用开发:打造高效启动流程
【4月更文挑战第5天】 在移动应用的世界中,用户的第一印象至关重要。特别是对于安卓应用而言,启动时间是用户体验的关键指标之一。本文将深入探讨如何优化安卓应用的启动流程,从而减少启动时间,提升用户满意度。我们将从分析应用启动流程的各个阶段入手,提出一系列实用的技术策略,包括代码层面的优化、资源加载的管理以及异步初始化等,帮助开发者构建快速响应的安卓应用。