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用于保存多功能日历中所有的日历元素
privateArrayListelements=new
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天,