基于Android的自定义通用可视化控件①

2017-02-20 07:40郑秋梅
计算机系统应用 2017年1期
关键词:折线图柱状图控件

郑秋梅, 刘 真, 苏 政, 李 松



基于Android的自定义通用可视化控件①

郑秋梅, 刘 真, 苏 政, 李 松

(中国石油大学(华东) 计算机与通信工程学院, 青岛 266580)

基于存在Android系统控件不能完全满足开发人员需求的情况, 提出一种自定义通用可视化控件, 介绍了基于Android开发的UI设计原理和图表的实现方法, 着重讨论了该自定义控件中使用的AsyncTask异步任务机制. 控件包括圆形图、柱状图和折线图三个图表, 其中圆形图可以动态地显示. 应用实验表明, 该控件修改简单, 使用方便, 具有较强的通用性.

Android; 自定义; 控件; 异步; 通用性

在进行Android应用系统开发时, 经常需要使用各种系统控件来设计UI(用户界面). Android系统本身提供了许多控件, 经常用到的有: 文本框(TextView)与编辑框(EditText)、按钮(Button)与图片按钮(ImageButton)、单项选择(RadioGroup)与复选框(CheckBox)、图片视图(ImageView)、状态开关按钮(ToggleButton)和时钟(AnalogClock和DigitalClock)等. 此外, 还可以使用一些高级控件, 如下拉列表(Spinner)、进度条(ProgressBar)和滚动视图(ScrollView)等[1]. 大多数情况下这些Android系统控件可以满足应用开发的需求, 但仍然存在现有控件不能完全实现系统功能的问题. 例如有时系统需要设计图表控件来显示数据, Web开发中有比较多的开源方案, 图表绘制相对较容易. 但在Android系统中的开源方案并不多, 因此需要开发者从现有的控件派生或重写控件属性、方法或事件来创建自定义控件, 实现用户的特殊需求.

自定义控件是一项十分灵活的新兴技术, 具有可编程性和可复用性. 该技术对外部环境开放且能被各种环境使用, 正被越来越多的应用程序开发者所关注. 鉴于自定义控件的灵活性以及应用程序支持插入控件这个功能[2-5], 本文通过设计一个基于Android的自定义通用控件, 实现了统计数据的可视化展示. 该控件由圆形图、柱状图和折线图三个图表组成, 通过自定义View层和设置Paint、Canvas等类的属性实现它们的绘制, 并采用AsyncTask异步任务机制重写其中关键方法, 实现后台任务初始化、调用webservice接口和将后台任务结果更新到UI等功能. 本文自定义控件的通用性体现在: 一是可通过更改输入数据来实现类似的统计可视化问题, 二是可增加或修改绘制图表的类, 实现任意图表的显示. 该控件已应用于开发完成的手机端数字校园系统中, 实现用户对校园一卡通消费统计的查询功能.

1 关键技术介绍

1.1 View层介绍

在开发一款手机应用软件时, UI设计是其中至关重要的部分. 好的用户界面能够激发用户的兴趣, 给其带来优越的用户体验. Android系统借助了Java的UI设计思想, 包括事件响应机制和布局管理, 给开发人员提供了诸如菜单、对话框、按钮和进度条等丰富的可视化用户界面. 这使得开发者能够为广大的Android用户设计出非常人性化、极具亲切感的界面[6].

View是Android系统中图形界面的基类, 提供给用户可视化的界面. View又分为两个子类, 即View和ViewGroup. 其中View包含一些基本组件, 例如菜单、按钮、列表等, 一个View对应界面上的一个矩形区域, 它负责该区域的属性设置和事件处理等. 而ViewGroup则可以看成是容纳View的一个容器, 负责装载和管理界面上的各种View来排列布局. Android的用户界面都是由View和ViewGroup以及它们的派生类组合而成的, 因此UI可以用View的树形结构来表示, 如图1所示.

图1 Android用户界面树形结构图

对于本文设计的自定义控件, 图表的可视化是其最终目的, 因此自定义View层并为其增加属性是重要任务.

1.2 绘制图形

本文讨论的问题中, 需要将数据的统计结果以图表的方式进行清晰直观的可视化展示, 因此需要绘制图形. Android的graphics包提供了很多操作二维图形的类, 可以利用这些类来实现绘图功能. 在本控件中, 为圆形图、柱状图和折线图分别定义了ICardConsume Arc、ICardConsumeColume和ICardConsumeLine三个继承自View的类来实现各自的绘图功能, 其中主要用到的工具类有Paint、Canvas和Path.

① Paint: 要实现绘图功能, 首先需要画笔工具, Paint类便是Android的画笔. 它包含了绘制几何图形、文本和位图所需的一些风格和颜色信息, 如线宽、字体和大小等. 通过Paint类提供给用户的公共方法, 可以对其属性进行设置[6].

② Canvas: 各类图形是要在一张画布上绘制的, Canvas类则实现了画布这一功能. 在绘制图形之前, 需要对Canvas设置一些画布的属性, 如画布的颜色、尺寸等[6].

③ Path: 在进行画线等操作时还需要连接路径, 这个工具由Path提供[6,7], Path类中包含一些直线或曲线连接到指定点的方法. 该自定义控件中的折线图则使用Path类进行直线的连接.

合理利用这些工具类, 则可以在手机界面设计并绘制开发人员需要的各种可视化图形.

1.3 AsyncTask异步任务机制

由于本文设计的自定义控件包含圆形图、柱状图和折线图三个图表, 且跳转到该功能Activity时, 三个图表的后台任务是并发执行的, 因此涉及多线程异步任务处理问题.

在Android中实现异步任务机制有Handler和AsyncTask两种方式. 前者需要为每一个任务创建一个新的线程, 任务完成后通过Handler实例向UI线程发送消息, 完成界面的更新. 这种方式对于整个过程的控制比较精细, 可以处理较为复杂的线程间通信及消息处理, 但也存在缺点, 例如代码相对臃肿, 在多个任务同时执行时, 不易对线程进行精确的控制等. AsyncTask是Android提供的一个轻量级的基于多线程的进行后台异步工作处理的类, 在后台的工作比较简单, 只需要向UI线程传递一些简单数据, 不再需要编写任务线程和Handler实例, 只使用AsyncTask类即可[8]. 使用AsyncTask类的方法是创建一个子类, 重写该类中的相关方法, 通过在UI线程中调用execute()方法运行这个自定义类.

使用AsyncTask类时, 要重写它的子类. 需要重写的方法如下:

① onPreExecute(): 当后台任务的execute()方法被调用后, 该方法立即执行, 一般用于一些初始化操作和在界面上显示后台任务的初始状态.

② doInBackground(Params…): 当onPreExecute()方法被调用后, 该方法被执行, 用于执行一些较为费时的后台任务. 在任务执行过程中可以调用publishProgress(Progress…)方法来更新程序界面.

③onProgressUpdate(Progress…): 在调用publishProgress(Progress…)方法后, 该方法被执行用来将进度信息更新到UI上.

④ onPostExecute(Result): 当后台任务全部执行结束后, 该方法被调用, 用来将计算结果更新显示到用户界面[9].

上述方法包含3类参数. Params表示后台任务执行时传入参数的类型; Progress表示后台任务执行的进度; Result表示后台任务执行结束后返回计算结果的类型. 在本文自定义控件的图表中都要重写上述4个方法.

2 通用控件设计实现及展示

在目前比较流行的掌上数字校园应用中, 针对一卡通消费问题, 学生们除了希望可以查询每次消费的相关明细外, 还经常关心自己一个月之内总的消费金额、分类消费金额和每日消费金额等. 下面具体介绍该控件的设计和实现过程.

2.1 界面布局

ViewGroup类是View类的子类, 是所有组件的容器, 界面的布局管理器作为ViewGroup的子类, 负责控制Android中各个组件的大小、间距和对齐方式等[10]. 本文的自定义控件用来统计近一个月内的消费情况, 主要实现三个功能: 圆形图显示总消费金额, 柱状图显示分类消费金额, 折线图显示每日消费金额. 界面布局如图2所示.

图2 界面布局设计

该界面还设计了两个HorizontalScrollView(横向滚动条), 用于显示完整的柱状图和折线图. 柱状图用来显示一个月的分类消费金额, 折线图则显示每日消费金额. 由于要显示的内容较多, 一般的手机屏幕显示不全, 因此使用HorizontalScrollView实现水平方向的滑动来查看完整信息.

2.2 图表设计

本文自定义控件涉及圆形图、柱状图和折线图三个图表, 且各自元素不同, 因此定义了三个绘制图表的类.

① 圆形图: 定义ICardConsumeArc类来绘制. 与柱状图和折线图的定义不同, 圆形图的设计思路为: 跳转到该界面时, 圆形图内部为动态增长的近一个月的消费金额总数, 外部是动态增长的圆形弧线. 数字与圆弧的动态增长是同步的, 当圆形弧线封闭时, 数字增长结束, 最终显示的数字即为近一个月一卡通的消费金额总数. 此功能涉及多线程问题, 因此定义了一个实现Runnable接口的thread类. 线程对象创建后, 需要通过调用线程的start()方法来启动线程[11]. 在线程类中最关键的是重写run()方法, 它包含了线程进入后台任务执行状态时要执行的代码, 该控件的run()方法直接调用postInvalidate()刷新界面, 实现数字和圆形弧线同步动态增长. 该类还调用了一个自定义的方法init(param), 负责画布和画笔的初始化操作.

② 柱状图: 定义ICardConsumeColume类来绘制. 该部分通过调用后台服务器的getFenleiConsume接口, 读取webservice信息, 将一卡通消费记录按不同的类别显示到该界面. 后台服务器中自定义的消费类别有水果店、超市、餐厅、开水房、图书馆等. ICardConsumeColume类中同样包含设置画笔属性和动态布局的init(param)方法. 在onDraw(Canvas)方法中, 本文调用了两个自定义方法drawRectf(Canvas)和drawName(Canvas), 前者用来绘制柱状图中的矩形柱, 后者显示类别名. 在控件的实际运行过程中, 各类别矩形柱的背景颜色会在一定范围内随机变化, 这是因为该类定义了一个存储背景颜色的数组, 其中包含7种用int类型标记的颜色, 在drawRectf(Canvas)方法中通过产生1-7之间的随机数来显示对应颜色.

③ 折线图: 定义ICardConsumeLine类来绘制. 同理, 该部分调用服务器的getMonthConsume接口, 读取并显示近一个月的每日消费金额. 根据测试手机屏幕尺寸, 在init(param)方法中预先定义手机屏幕可显示8天的记录, 通过水平滑动显示剩余记录. 该类中onDraw(Canvas)调用了drawStraightLine(Canvas)和drawBrokenLine(Canvas)两个方法, 分别用来绘制竖线和折线. 在绘制折线时, 还定义了Path类的对象, 用于连点成线.

2.3 主Activity的设计

在一卡通功能的Activity点击相关图标会跳转到该自定义控件的主Activity, 将其命名为ICardGraphMainActivity. 在该java文件中, 本文为柱状图和折线图的异步任务处理各自定义了AsyncTask的子类: ColumTask和LineTask, 由于圆形图中显示的总消费金额可从柱状图访问的服务器接口获得, 因此不再另外定义类来处理. 在这两个子类中, 重写了上文中提到的异步任务机制的4个方法. 由于项目前期已将后台服务器搭建完毕, 本控件中需要的近一个月的分类消费记录和每日消费记录可直接调用服务器的getFenleiConsume和getMonthConsume接口, 读取WebService信息[11-13]. 以柱状图为例, 在ICardGraphMainActivity类的onCreate方法中调用execute()以后, 便执行onPreExecute()方法; 紧接着doInBackground(Params)执行, 该方法负责访问服务器的getFenleiConsume接口读取分类消费信息, 并调用publishProgress()更新程序界面; 随后onProgressUpdate(Params)执行, 将进度信息更新到UI界面上; 最后调用onPostExecute(Result), 给计算结果赋值并显示到用户界面[14,15].

2.4 应用实例及效果展示

本文自定义的通用控件目前已应用于开发完成的数字校园手机端系统, 近一个月消费统计的最终展示效果如图3.

(a) 随机状态1    (b) 随机状态2    (c) 随机状态3

图3中最上方圆形图的中心数字表示总消费金额, 外围的白色圆环与中心数字同步动态增长, 数字增长结束时圆环闭合, (a)(b)(c)为随机截取的三个状态.

本文的自定义图表控件给类似的统计问题提供了一个模板, 只要输入的原始数据符合一定格式, 均可以使用该控件实现用户的展示需求. 其中实现分类功能的柱状图的输入数据需满足格式:

实现每日消费的折线图的输入数据格式为:

除了校园一卡通的消费统计以外, 本文还通过自定义模拟数据, 实现了家电销售统计和个人财务管理两个类似的典型案例, 图4展示了近一个月家电销售情况, 图5为近一个月个人生活支出情况.

3 通用控件效果评价

如上文的控件展示图所示, 圆形图的动态变化是本文自定义控件的一个亮点, 随着中心数字和外围曲线的同步增长, 师生对本月的总消费金额会有一个心理上的变化, 相比现有的大部分图表控件的直接静态显示, 具有更优的用户体验. 若该控件应用在其他系统, ICardConsumeColume类中数组内的颜色范围也可随意设定, 本文设置了7种矩形柱颜色, 使得每次跳转到该Activity时, 分类矩形柱的填充颜色都是不同的, 可视化效果比固定颜色设置的方式更加灵活.

尽管目前也有一些基于Android界面设计的自定义可视化控件开源案例, 相比部分相似案例[16,17], 本文提出的自定义控件从使用条件和可视化方式等方面都具有一定的创新性和新颖性, 对比如表1所示.

表1 本文控件与现有相似成果的对比评估

上表中的通用性指控件的适用条件, 本文的自定义控件包含圆形图、柱状图和折线图三种图表, 若根据用户需求想显示任意其他种类的图表, 只需添加或删改绘制相应的图表类, 并在ICardGraphMainActivity中重新调用即可. 而现有的类似成果中, 自定义控件一般对所属系统的依赖性较强, 系统功能改变, 图表控件需要作出较大的改动, 相比之下, 本文提出的自定义控件具有较强的通用性.

美观性方面, 本文控件的背景颜色和填充颜色等均由参数控制, 可根据用户需求修改设置成不同的皮肤使用, 三个图表在同一个界面可全部显示. 而在对比的控件中, 图表不能完全占据手机屏幕, 且用色简单, 本文控件布局相对更加合理, 具有较好的美观性.

用户体验方面, 跳转到该控件所在界面时, 用户无需任何操作, 圆形图自动动态增长, 柱状图颜色随机显示. 相对于部分已有控件来说, 该控件更容易掌握且灵活性强, 用户体验更佳.

4 结语

本文提出的基于Android的自定义通用可视化控件能解决各种类似的数据统计问题, 该控件在满足一定格式要求的条件下, 只需要替换输入数据, 即可实现圆形图、柱状图、折线图三类图表的可视化展示; 控件通用性较强, 若需要展示其他任意类型图表, 只需额外增加绘制该图表的类或修改当前类, 并略加修改布局和主Activity即可; 该控件能够实现圆形图中心数字和外围曲线的同步动态增长以及柱状图填充颜色的随机显示, 相比现有的部分图表控件具有更好的用户体验效果, 但仍可进一步改进.

1 李维勇.Android UI设计.北京:机械工业出版社,2015.

2 曾健平,邵艳洁.Android系统架构及应用程序开发研究.微计算机信息,2011,27(9).

3 季玉茹,王德忠.基于安卓的音乐播放器设计.电脑知识与技术,2013,9(25):5641–5658.

4 徐虎,彭正涛,赵俊逸.基于WiFi的Android移动设备语音通信系统的设计开发.计算机应用与软件,2012,29(11): 225–238.

5 黄艺锋,闫巧.基于Android平台电子词典的设计与实现. 计算机应用,2011,31(2):228–232.

6 罗雷,韩建文,汪杰.Android系统应用开发实战详解.北京: 人民邮电出版社,2014.

7 李刚.疯狂Android讲义.北京:电子工业出版社,2011.

8 杨杰.基于Android的多线程处理技术.电脑知识与技术,2013,9(18):4251–4254.

9 李光明,孙英爽,党小娟.基于安卓的远程监控系统的设计与实现.计算机工程与设计,2016,37(2):556–561.

10 Ostrander J,刘文斌,译.Android UI基础教程:Develop& Design.北京:人民邮电出版社,2012.

11 巫志勇.Android开发中Web Service网络编程研究.电脑知识与技术,2012,8(20):4904–4906.

12 罗国涛,裴广.基于WebService和Android的C/S+B/S结构手机电影系统.计算机应用与软件,2015,32(9):328–333.

13 倪凯,夏海波,魏建明,程嘉昇,李焱.一种移动终端远程数据访问控制方法.计算机应用与软件,2012,29(6):230–232.

14 彭海文.Android Web Services应用研究.电脑知识与技术, 2011,7(12):2851–2852.

15 陈望挺,林满足,陈健,章跃,傅奇佳,竺乐庆.基于JSP和Android的C/S结构问卷系统.计算机应用,2013,33(3): 886–889.

16 李双麟.基于Android的智能供水控制系统的设计与实现[硕士学位论文].长春:吉林大学,2015.

17 秦建波,王巍,李冬晨.基于Android 的股市App的技术研究与实现.电脑知识与技术,2014,10(32):7653–7656.

Custom General Visual Component Based on Android

ZHENG Qiu-Mei, LIU Zhen, SU Zheng, LI Song

(College of Computer and Communication Engineering, China University of Petroleum, Qingdao 266580, China)

Since Android system components cannot fully meet the needs of developers, this paper proposes a custom general visual component, introduces the UI design principles based on Android and the realization methods of tables, and mainly discusses the asynchronous task mechanism used in the custom component. This component includes a circular diagram, a histogram and a line chart, and the circular diagram can display dynamically. Experimental results show that the component is simple and easy to use, and also has a strong commonality.

Android; custom; component; asynchronous; commonality

国家自然科学基金(51274232,61305008);中央高校基本科研业务费专项(14CX06008A);山东省自然科学基金(ZR2011FQ018)

2016-04-14;收到修改稿时间:2016-06-12

[10.15888/j.cnki.csa.005584]

猜你喜欢
折线图柱状图控件
使用“填表单”微信小程序 统计信息很方便
基于.net的用户定义验证控件的应用分析
数据增加折线图自动延长
关于.net控件数组的探讨
让折线图显示在一个单元格中
再多也不乱 制作按需显示的折线图
高中地理图像图表题解析技巧之管窥
美化Excel折线图表
由科研论文中一个柱状图引发的编辑思考
应用EXCEL和MAPGIS快速生成地浸砂岩型铀矿钻孔综合柱状图