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,如需转载请自行联系原作者
相关文章
|
14天前
|
Android开发 开发者 Kotlin
探索安卓开发中的新特性
【9月更文挑战第14天】本文将引导你深入理解安卓开发领域的一些最新特性,并为你提供实用的代码示例。无论你是初学者还是经验丰富的开发者,这篇文章都会给你带来新的启示和灵感。让我们一起探索吧!
|
2天前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
|
9天前
|
Android开发 开发者
安卓开发中的自定义视图:从入门到精通
【9月更文挑战第19天】在安卓开发的广阔天地中,自定义视图是一块充满魔力的土地。它不仅仅是代码的堆砌,更是艺术与科技的完美结合。通过掌握自定义视图,开发者能够打破常规,创造出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战应用,一步步展示如何用代码绘出心中的蓝图。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往创意和效率的大门。让我们一起探索自定义视图的秘密,将你的应用打造成一件艺术品吧!
31 10
|
2天前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
|
10天前
|
Java Linux Android开发
深入理解Android开发:从基础到高级
【9月更文挑战第17天】本文将深入探讨Android开发的各个方面,包括应用开发、操作系统等。我们将通过代码示例来展示如何创建一个简单的Android应用,并解释其背后的原理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和启示。
|
8天前
|
存储 Java Android开发
🔥Android开发大神揭秘:从菜鸟到高手,你的代码为何总是慢人一步?💻
在Android开发中,每位开发者都渴望应用响应迅速、体验流畅。然而,代码执行缓慢却是常见问题。本文将跟随一位大神的脚步,剖析三大典型案例:主线程阻塞导致卡顿、内存泄漏引发性能下降及不合理布局引起的渲染问题,并提供优化方案。通过学习这些技巧,你将能够显著提升应用性能,从新手蜕变为高手。
15 2
|
9天前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
38 1
|
13天前
|
XML 编解码 Android开发
安卓开发中的自定义视图控件
【9月更文挑战第14天】在安卓开发中,自定义视图控件是一种高级技巧,它可以让开发者根据项目需求创建出独特的用户界面元素。本文将通过一个简单示例,引导你了解如何在安卓项目中实现自定义视图控件,包括创建自定义控件类、处理绘制逻辑以及响应用户交互。无论你是初学者还是有经验的开发者,这篇文章都会为你提供有价值的见解和技巧。
25 3
|
15天前
|
前端开发 Android开发 开发者
安卓应用开发中的自定义视图基础
【9月更文挑战第13天】在安卓开发的广阔天地中,自定义视图是一块神奇的画布,它允许开发者将想象力转化为用户界面的创新元素。本文将带你一探究竟,了解如何从零开始构建自定义视图,包括绘图基础、触摸事件处理,以及性能优化的实用技巧。无论你是想提升应用的视觉吸引力,还是追求更流畅的交互体验,这里都有你需要的金钥匙。
|
1天前
|
搜索推荐 前端开发 Android开发
安卓开发中的自定义视图:打造个性化用户界面
【9月更文挑战第26天】在移动应用开发的广阔天地中,定制性是提升用户体验的不二法宝。本文将带你深入了解安卓开发中自定义视图的魅力所在,通过简洁明了的语言和直观的代码示例,展示如何从零开始创建属于自己的控件,让你的应用界面与众不同。