Android日历完整实现.docx
- 文档编号:26363051
- 上传时间:2023-06-18
- 格式:DOCX
- 页数:34
- 大小:156.84KB
Android日历完整实现.docx
《Android日历完整实现.docx》由会员分享,可在线阅读,更多相关《Android日历完整实现.docx(34页珍藏版)》请在冰豆网上搜索。
Android日历完整实现
实用第一智慧密集
2011.05
实现基于Android的日历系统
摘要:
Android作为目前较为流行的智能手机操作系统已成为大多数人的首选。
在美国乃至世界
的很多地方的出货量已经超越Iphone,成为世界上最大智能手机操作系统。
因此,世界各地的程
序员都跃跃欲试地想学习Android的开发,并希望从中捞得属于自己的第一桶金。
在此给出一个
基于Android的日历系统的完整实现过程。
关键词:
Android;日历;绘画;农历;记录;提醒
1引言
要实现的日历除了常规的日历功能外,还可以显示与当前
日期相关的信息,如当前日期的农历日期、天干地支、节日等
信息。
下面先看看日历的绚丽界面,如图1、图2所示。
主要功能
2绘画基础
由于实现的日历系统要涉及到大量的Android绘图技术,
因此,要简单介绍Android的绘图技术。
绘制图形通常在Android.view.View或其子类的onDraw方
法中进行。
该方法的定义如下:
protectedvoidonDraw(Canvascanvas);
其中Canvas对象提供了大量用于绘图的方法,这些方法
主要包括绘制像素点、直线、圆形、弧、文本,这些都是组成
复杂图形的基本元素。
如果要画更复杂的图形,可以采用组合
这些图形基本元素的方式来完成。
例如,可以采用画3条直线
的方式来画三角形。
下面来看一下绘制图形基本元素的方法。
2.1绘制像素点
publicnativevoiddrawPoint(floatx,floaty,Paintpaint);
//画一个像素点
publicnativevoiddrawPoints(float[]pts,intoffset,intcount,
Paintpaint);//画多个像素点
publicvoiddrawPoints(float[]pts,Paintpaint);
//画多个像素点
参数的含义如下:
(1)x:
像素点的横坐标。
(2)y:
像素点的纵坐标。
(3)paint:
描述像素点属性的Paint对象。
可设置像素点
的大小、颜色等属性。
绘制其他图形元素的Paint对象与绘制
像素点的Paint对象的含义相同。
在绘制具体的图形元素时可
根据实际的情况设置Paint对象。
(4)pts:
drawPoints方法可一次性画多个像素点。
pts参数
表示多个像素点的坐标。
该数组元素必须是偶数个,两个一组
为一个像素点的坐标。
(5)offset:
drawPoints方法可以取pts数组中的一部分连
续元素作为像素点的坐标,因此,需要通过offset参数来指定
取得数组中连续元素的第一个元素的位置,也就是元素偏移
量,从0开始。
例如,要从第3个元素开始取数组元素,那么
offset参数值就是2。
(6)count:
要获得的数组元素个数,count必须为偶数
(两个数组元素为一个像素点的坐标)。
要注意的是,offset可以从任意一个元素开始取值,例如,
offset可以为1,然后count为4。
2.2绘制直线
publicvoiddrawLine(floatstartX,floatstartY,floatstopX,
floatstopY,Paintpaint);//画一条直线
publicnativevoiddrawLines(float[]pts,intoffset,intcount,
Paintpaint);//画多条直线
publicvoiddrawLines(float[]pts,Paintpaint);
//画多条直线
参数的含义如下:
(1)startX:
直线开始端点的横坐标。
(2)startY:
直线开始端点的纵坐标。
(3)stopX:
直线结束端点的横坐标。
(4)stopY:
直线结束端点的纵坐标。
(5)pts:
绘制多条直线时的端点坐标集合。
4个数组元素
(两个为开始端点的坐标,两个为结束端点的坐标)为1组,
表示一条直线。
例如,画两条直线,pts数组就应该有8个元
素。
前4个数组元素为第1条直线两个端点的坐标,后4个数
组元素为第2条直线的两个端点的坐标。
(6)offset:
pts数组中元素的偏移量。
(7)count:
取得pts数组中元素的个数。
该参数值需为4
的整数倍。
2.3绘制圆形
publicvoiddrawCircle(floatcx,floatcy,floatradius,Paint
paint);
参数的含义如下:
(1)cx:
圆心的横坐标。
(2)cy:
圆心的纵坐标。
(3)radius:
圆的半径。
2.4绘制弧
publicvoiddrawArc(RectFoval,floatstartAngle,float
sweepAngle,booleanuseCenter,Paintpaint);
参数的含义如下:
(1)oval:
弧的外切矩形的坐标。
需要设置该矩形的左上
角和右下角的坐标,也就是oval.left、oval.top、oval.right和
oval.bottom。
(2)startAngle:
弧的起始角度。
(3)sweepAngle:
弧的结束角度。
如果sweepAngle-startAngle
的值大于等于360,drawArc画的就是一个圆或椭圆(如
果oval指定的坐标画出来的是长方形,drawArc画的就是椭圆)。
(4)useCenter:
如果该参数值为true,在画弧时弧的两个端
点会连接圆心。
如果该参数值为false,则只会画弧。
效果如图3
所示。
前两个弧未设置填充状态,后两个弧设置了填充状态。
2.5绘制文本
//绘制text指定的文本
publicnativevoiddrawText(Stringtext,floatx,floaty,Paint
paint);
//绘制text指定的文本。
文本中的每一个字符的起始坐标由
//pos数组中的值决定。
publicvoiddrawPosText(Stringtext,float[]pos,Paintpaint);
//绘制text指定的文本。
text中的每一个字符的起始坐标由
//pos数组中的值决定。
并且可以选择text中的某一段
//连续的字符绘制
publicvoiddrawPosText(char[]text,intindex,intcount,float
[]pos,Paintpaint);
参数的含义如下:
(1)text:
drawText方法中的text参数表示要绘制的文本。
drawPostText方法中的text虽然也表示要绘制的文本,但每一
个字符的坐标需要单独指定。
如果未指定某个字符的坐标,系
统会抛出异常。
(2)x:
绘制文本的起始点的横坐标。
(3)y:
绘制文本的起始点的纵坐标。
(4)index:
选定的字符集合在text数组中的索引。
(5)count:
选定的字符集中字符个数。
3绘制日历的框架
从图1可以看出,日历的上部是3行文字,显示了当前日
期的相关信息。
下面来看看如何布局显示这些文字的组件。
在日历主界面的上半部需要放置4个组件,1个ImageView
组件和3个TextView组件。
其中ImageView组件用于
显示左上角的图像。
3个TextView组件用于显示当前日期的信
息。
由于目前还没有当前日期的信息。
因此,这3个TextView
组件暂时设置了固定的信息。
下面开始在main.xml文件中设置这4个组件。
在修改
main.xml文件的内容之前,先复制一个calendar.png文件,作
为日历的logo(修改AndroidManifest.xml文件中的应用程序图
标)。
建立一个Calendar工程,并编写main.xml文件。
xmlversion="1.0"encoding="utf-8"?
>
android="http: //schemas.android. com/apk/res/android" android: orientation="vertical"android: layout_width=" fill_parent" android: layout_height="fill_parent"android: background=" @color/calendar_background"> --android: background=" @drawable/background"--> id="@+id/calHeader"android: layout_width="fill_parent" android: layout_height="70dp"> id="@+id/ivLogo"android: src="@drawable/calendar_bak" android: layout_width="@dimen/logo_size"android: layout_height="@dimen/logo_size" android: layout_margin="@dimen/margin"/> layout_width="fill_parent" android: layout_height="wrap_content"android: layout_toRightOf="@id/ivLogo" android: layout_marginTop="@dimen/margin" android: orientation="vertical"> id="@+id/tvMsg1"android: layout_width="fill_parent" android: layout_height="wrap_content" android: textColor="@color/text_color"/> id="@+id/tvMsg2" android: layout_width="fill_parent" android: layout_height="wrap_content" android: textColor="@color/text_color"/> id="@+id/tvMsg3"android: layout_width="fill_parent" android: layout_height="wrap_content" android: textColor="@color/text_color"/> 下面在Main类的Oncreate方法中编写代码装载main.xml: publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); LinearLayoutmainLayout=(LinearLayout)getLayoutInflater(). inflate(R.layout.main,null); setContentView(mainLayout); //需要向mainLayout中加入日历网络 } 在绘制日历之前,要先介绍一下日历绘制的方法。 虽然从 底层技术来看,绘制日历是在onDraw方法中完成的。 但在本 系统中将要绘制的部分分成了很多块。 而这些要绘制的块都需 要放在一个叫CalendarView的类中,代码如下: publicclassCalendarViewextendsView { privateActivityactivity; @Override protectedvoidonDraw(Canvascanvas) {} publicCalendarView(Activityactivity) { super(activity); this.activity=activity; } } 在编写完CalendarView类后,需要在Main类中定义该类 的变量,并在onCreate方法中创建类的对象实例,代码如下: privateCalendarViewcalendarView; calendarView=newCalendarView(this); mainLayout.addView(calendarView); 在前面已经介绍过,在本系统中会将要绘制的日历分成若 干块,而每一块都需要有同样的接口,以便统一绘制它们。 因 此,这些块都要实现一个CalendarElement接口。 这些要绘制的块包括日历边框、网络、日历头等,而在 CalendarElement接口中有一个draw方法。 在绘制日历元素时只 需调用draw方法即可。 在后面的实现中会看到更多实现CalendarElement 接口的类,下面先来编写CalendarElement接口。 packageproject.calendar.interfaces; importandroid.graphics.Canvas; publicinterfaceCalendarElement { publicvoiddraw(Canvascanvas); } packageproject.calendar.interfaces; importandroid.graphics.Canvas; publicinterfaceCalendarElement { publicvoiddraw(Canvascanvas); } 现在需要一个总的类来绘制上述的这些块。 这个功能由 Calendar类来完成。 Calendar是一个总的日历元素类,在该类 的draw方法中绘制了所有的日历元素。 Calendar是第一个实现 CalendarElement接口的类,代码如下: publicclassCalendarextendsCalendarParent { //elements用于保存多功能日历中所有的日历元素 privateArrayList ArrayList publicCalendar(Activityactivity,Viewview) { super(activity,view); } @Override publicvoiddraw(Canvascanvas) { //在draw方法中通过扫描elements变量来获得所 //有日历元素的对象,并调用draw方法绘制这些日历元素 for(CalendarElementce: elements) ce.draw(canvas); } } 在CalendarView类中需要调用Calendar类来绘制日历,因 此,需要在CalendarView类中创建Calendar类的对象实例,并 调用draw进行绘制,代码如下: publicCalendarce; @Override protectedvoidonDraw(Canvascanvas) { ce.draw(canvas); } publicCalendarView(Activityactivity) { ce=newCalendar(activity,this); } 下面编写第一个绘制元素类: Border。 Border类用于绘制 日历的边框,该类是日历元素类,需要实现CalendarElement 接口,不过该类只要继承刚实现的CalendarParent类即可。 publicclassBorderextendsCalendarParent { publicBorder(Activityactivity,Viewview) { super(activity,view); //注意,一定要4个字节的颜色值,包括一个透明色 paint.setColor(0xFFFFFFFF); } @Override publicvoiddraw(Canvascanvas) { floatleft=borderMargin; floattop=borderMargin; floatright=view.getMeasuredWidth()-left; floatbottom=view.getMeasuredHeight()-top; canvas.drawLine(left,top,right,top,paint); canvas.drawLine(right,top,right,bottom,paint); canvas.drawLine(right,bottom,left,bottom,paint); canvas.drawLine(left,bottom,left,top,paint); Log.d("draw",String.valueOf(right)); } } Grid类用于绘制日历的网格,该类是日历元素类,需要继 承CalendarParent类。 publicclassGridextendsCalendarParent { privatefloattop,left; @Override publicvoiddraw(Canvascanvas) { left=borderMargin; top=borderMargin+weekNameSize+weekNameMargin* 2+4; floatcalendarWidth=view.getMeasuredWidth()-left*2; floatcalendarHeight=view.getMeasuredHeight()-top- borderMargin; floatcellWidth=calendarWidth/7; floatcellHeight=calendarHeight/6; paint.setColor(0xFFFFFFFF); canvas.drawLine(left,top,left+view.getMeasuredWidth() -borderMargin*2,top,paint); paint.setColor(0xFF666666); //画横线 for(inti=1;i<6;i++) { canvas.drawLine(left,top+(cellHeight)*i,left+calendar- Width, top+(cellHeight)*i,paint); } //画竖线 for(inti=1;i<7;i++) { canvas.drawLine(left+cellWidth*i,top,left+cellWidth*i, view.getMeasuredHeight()-borderMargin,paint); }} publicGrid(Activityactivity,Viewview) { super(activity,view); //TODOAuto-generatedconstructorstub }} Week类用于显示日历网格上方的星期文本: publicclassWeekextendsCalendarParent { privateString[]weekNames=newString[] {"日","一","二","三","四","五","六"}; privateintweekNameColor; publicWeek(Activityactivity,Viewview) { super(activity,view); weekNameColor=Color.WHITE; paint.setTextSize(weekNameSize); } @Override publicvoiddraw(Canvascanvas) { floatleft=borderMargin; floattop=borderMargin; floateveryWeekWidth=(view.getMeasuredWidth()-borderMargin *2)/7; paint.setFakeBoldText(true); for(inti=0;i { if(i==0||i==weekNames.length-1) paint.setColor(sundaySaturdayColor); else paint.setColor(weekNameColor); left=borderMargin+everyWeekWidth*i +(everyWeekWidth-paint.measureText(weekNames[i]))/ 2; canvas.drawText(weekNames[i],left,top+paint.getTextSize ()+ weekNameMargin,paint); }}} 4核心技术 前面介绍了绘制日历的基本方法,现在将逐步接触到日历 系统的核心技术。 首先来看一下日历中如何表示日期。 在Grid类中的days数组保存了42个数字。 这42个数字 就是日历主界面中的6*7个方格中的数字。 这些数字分为两部 分,中间的部分就是当前月中的天数。 这些天数最小是28天,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 日历 完整 实现