版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章Android图形与动画7.1绘图
7.2动画
7.3小结
7.1绘图
7.1.1View类绘图程序框架
借助View类绘图,需要在View类的onDraw方法添加绘图语句,然后在应用程序中显示该View视图。如果只是单纯地绘制几个图形,Android系统会管理View视图的显示刷新工作,而程序员无需编写刷新代码,如例7.1所示。
例7.1View类简单绘图程序示例。
例7.1的运行结果如图7-1所示,即显示一个填充圆和圆圈。图7-1例7.1运行结果(填充圆和圆圈为红色)新建工程ex07_01,应用名为MyViewDrawApp,包名为cn.jxufe.zhangenhe,活动界面名为MyViewDrawAct。工程ex07_01包括源代码文件MyViewDrawAct.java和MySimpleView.java等。其中,文件MySimpleView.java负责绘图工作,而MyViewDrawAct.java负责显示。
MySimpleView.java文件的代码如下所示:
1packagecn.jxufe.zhangenhe;
2
3importandroid.content.Context;
4importandroid.graphics.Canvas;
5importandroid.graphics.Color;
6importandroid.graphics.Paint;
7importandroid.graphics.Paint.Style;
8importandroid.view.View;
9
10publicclassMySimpleViewextendsView{
11 publicMySimpleView(Contextcontext){
12 super(context);
13 //TODOAuto-generatedconstructorstub
14 }
第10行说明MySimpleView类继承了View类。第11~14行为MySimpleView类的构造函数。
15 @Override
16 protectedvoidonDraw(Canvascanvas){
17 Paintpaint=newPaint();
18 paint.setColor(Color.RED);
19 paint.setStyle(Style.FILL);
20 canvas.drawColor(Color.DKGRAY);
21 canvas.drawCircle(100,100,50,paint);
22 for(inttheta=0;theta<360;theta++){
23 floatx=(float)(50*Math.sin(theta*Math.PI/180.0)+300);
24 floaty=(float)(50*Math.cos(theta*Math.PI/180.0)+100);
25 canvas.drawPoint(x,y,paint);
26 }
27 }
28}
文件MyViewDrawAct.java的内容如下所示:
1packagecn.jxufe.zhangenhe;
2
3i
mportandroid.app.Activity;
4importandroid.os.Bundle;
5
6publicclassMyViewDrawActextendsActivity{
7 privateMySimpleViewmySimpleView;
8/**Calledwhentheactivityisfirstcreated.*/
9@Override
10publicvoidonCreate(BundlesavedInstanceState){
11super.onCreate(savedInstanceState);
12myInitGUI();
13}
14privatevoidmyInitGUI(){
15 mySimpleView=newMySimpleView(this);
16 setContentView(mySimpleView);
17}
18}
例7.2View类单线程刷新绘图示例。
例7.1的onDraw方法是不变的即绘制的是静态图形,这时的应用程序无需程序员编写显示刷新代码,即无需调用invalidate方法。例7.2给出了一种单线程实现的View类绘图操作,需要程序员编写显示刷新代码,例7.2的执行结果如图7-2所示。图7-2例7.2执行结果汉字字符串资源文件mystrings_hz.xml的代码如下所示:
1<?xmlversion="1.0"encoding="utf-8"?>
2<resources>
3<stringname="strfilled">填充</string>
4<stringname="strstroke">不填充</string>
5<stringname="strcircle">绘圆</string>
6<stringname="strrect">绘矩形</string>
7</resources>
布局文件main.xml的代码如下所示,重点需要关注第52~58行关于自定义的View类的布局XML语言写法。
1<?xmlversion="1.0"encoding="utf-8"?>
2<AbsoluteLayout
3android:id="@+id/widget35"
4android:layout_width="fill_parent"
5android:layout_height="fill_parent"
6xmlns:android="/apk/res/android"
7android:background="@drawable/darkgray"
8>
9<RadioGroup
10android:id="@+id/rgshape"
11android:layout_width="180px"
12android:layout_height="130px"
13android:layout_x="20px"
14android:layout_y="20px"
15>
16<RadioButton
17android:id="@+id/rbfill"
18android:layout_width="wrap_content"
19android:layout_height="wrap_content"
20android:text="@string/strfilled"
21android:checked="true"
22>
23</RadioButton>
24<RadioButton
25android:id="@+id/rbstroke"
26android:layout_width="wrap_content"
27android:layout_height="wrap_content"
28android:text="@string/strstroke"
29>
30</RadioButton>
31</RadioGroup>
32<Button
33android:id="@+id/btcirc"
34android:layout_width="120px"
35android:layout_height="60px"
36android:text="@string/strcircle"
37android:layout_x="200px"
38android:layout_y="60px"
39android:onClick="myShowMD"
40>
41</Button>
42<Button
43android:id="@+id/btrect"
44android:layout_width="120px"
45android:layout_height="60px"
46android:text="@string/strrect"
47android:layout_x="340px"
48android:layout_y="60px"
49android:onClick="myShowMD"
50>
51</Button>
52<cn.jxufe.zhangyunzhi.MySimpleView
53android:id="@+id/myview"
54android:layout_width="480px"
55android:layout_height="400px"
56android:layout_x="0px"
57android:layout_y="160px"
58/>
59</AbsoluteLayout>上述代码中,第39、49行表示点击“绘圆”和“绘矩形”按钮(见图7-2)的事件响应方法均为myShowMD。
源文件MySimpleView.java的代码如下,重点介绍其与工程ex07_01中的同名文件的区别。
1packagecn.jxufe.zhangyunzhi;
2
3importandroid.content.Context;
4importandroid.graphics.Canvas;
5importandroid.graphics.Color;
6importandroid.graphics.Paint;
7importandroid.graphics.Paint.Style;
8importandroid.graphics.Rect;
9importandroid.util.AttributeSet;
10importandroid.view.View;
11
12publicclassMySimpleViewextendsView{
13 privateStylestyle=Style.STROKE;
14 privateintshape=0;
第13~14行定义了两个变量style和shape,分别表示填充方法和绘制圆形还是矩形,shape为0时绘圆;shape为1时绘矩形。
15 publicMySimpleView(Contextcontext,AttributeSetattr){
16 super(context,attr);
17 }必须采用第15~17行的构造方法,其中attr表示视图的属性。
18 publicvoidonDraw(Canvascanvas){
19 canvas.drawColor(Color.DKGRAY);
20 Paintpaint=newPaint();
21 paint.setColor(Color.RED);
22 paint.setStyle(style);
23 switch(shape){
24 case0:
25 canvas.drawCircle(100,100,50,paint);
26 break;
27 case1:
28 Rectr=newRect(100,100,200,150);
29 canvas.drawRect(r,paint);
30 break;
31 }
32 }
第22行通过变量style设置填充方式;第23~31行根据shape的值设置画圆还是画矩形,当shape为0时,画圆;当shape为1时,画矩形。
33 publicvoidsetStyle(Stylestyle,intshape){
34 this.style=style;
35 this.shape=shape;
36 }
37}
第33~36行的方法setStyle用于设置绘图的填充方法的变量style以及画圆还是画矩形的变量shape。
源文件MyViewDrawAct.java的代码如下所示,重点分析与工程ex07_01中的同名文件不同的地方。
1packagecn.jxufe.zhangyunzhi;
2
3importandroid.app.Activity;
4importandroid.graphics.Paint.Style;
5importandroid.os.Bundle;
6
importandroid.view.View;
7importandroid.widget.RadioButton;
8
9publicclassMyViewDrawActextendsActivity{
10 privateRadioButtonrbfilled,rbstroke;
11 privateMySimpleViewmySimpleView;
12/**Calledwhentheactivityisfirstcreated.*/
13@Override
14publicvoidonCreate(BundlesavedInstanceState){
15super.onCreate(savedInstanceState);
16setContentView(R.layout.main);
17myInitGUI();
18}第10行定义两个单选钮对象,表示图7-2中的“填充”和“不填充”单选钮(第21、22行)。第11行定义MySimpleView类的对象mySimpleView,该对象为布局文件中的myview(第20行)。第16行设置显示界面为main.xml布局文件的内容。
19privatevoidmyInitGUI(){
20 mySimpleView=(MySimpleView)findViewById(R.id.myview);
21 rbfilled=(RadioButton)findViewById(R.id.rbfill);
22 rbstroke=(RadioButton)findViewById(R.id.rbstroke);
23}
24publicvoidmyShowMD(Viewv){
25 intshape=0;
26 switch(v.getId()){
27 caseR.id.btcirc:
28 shape=0;
29 break;
30 caseR.id.btrect:
31 shape=1;
32 break;
33 }
34 if(rbfilled.isChecked()){
35 mySimpleView.setStyle(Style.FILL,shape);
36 }
37 if(rbstroke.isChecked()){
38 mySimpleView.setStyle(Style.STROKE,shape);
39 }
40 mySimpleView.postInvalidate();//mySimpleView.
invalidate();
41}
42}
例7.3View类多线程刷新绘图示列。
例7.3执行的结果与例7.2完全相同,如图7-2所示。
新建工程ex07_03,包名为cn.jxufe.zhanglanxiao,这个包名与工程ex07_02不同,工程ex07_03的应用名和活动界面名与工程ex07_02相同,为MyViewDrawApp和MyViewDrawAct。工程ex07_03包含源文件MyViewDrawAct.java、MySimpleView.java、MyThread.java、布局文件main.xml、颜色资源文件myguicolor.mxl和汉字字符串资源文件mystrings_hz.xml等。与工程ex07_02相比,新添加了一个文件MyThread.java,并且对MyViewDrawAct.java作了改动,其余文件与工程ex07_02中同名文件的内容完全相同,这里不再赘述。文件MyThread.java的内容如下所示:
1packagecn.jxufe.zhanglanxiao;
2
3importandroid.os.Bundle;
4importandroid.os.Handler;
5importandroid.os.Message;
6
7publicclassMyThreadextendsThread{
8 privateHandlerh;
9 privateMessagemsg;
10 publicMyThread(Handlerh){
11 //TODOAuto-generatedconstructorstub
12 this.h=h;
13 }
14 @Override
15 publicvoidrun(){
16 try{
17 Thread.sleep(100);
18 }
19 catch(InterruptedExceptione){
20 Thread.currentThread().interrupt();
21 }
22 msg=h.obtainMessage();
23 Bundlebd=newBundle();
24 bd.putInt("value",MyViewDrawAct.VIEW_FRESH);
25 msg.setData(bd);
26 h.sendMessage(msg);
27 }
28}
文件MyViewDrawAct.java的内容如下所示,重点分析与工程ex07_02的同名文件中不同的地方。
1packagecn.jxufe.zhanglanxiao;
2
3importandroid.app.Activity;
4importandroid.graphics.Paint.Style;
5importandroid.os.Bundle;
6importandroid.os.Handler;
7importandroid.os.Message;
8importandroid.view.View;
9importandroid.widget.RadioButton;
10
11publicclassMyViewDrawActextendsActivity{
12 publicstaticfinalintVIEW_FRESH=1;
13 privateRadioButtonrbfilled,rbstroke;
14 privateMySimpleViewmySimpleView;
15/**Calledwhentheactivityisfirstcreated.*/
16@Override
17publicvoidonCreate(BundlesavedInstanceState){
18super.onCreate(savedInstanceState);
19setContentView(R.layout.main);
20myInitGUI();
21}
22privatevoidmyInitGUI(){
23 mySimpleView=(MySimpleView)findViewById
(R.id.myview);
24 rbfilled=(RadioButton)findViewById(R.id.rbfill);
25 rbstroke=(RadioButton)findViewById(R.id.rbstroke);
26}
27publicvoidmyShowMD(Viewv){
28 intshape=0;
29 switch(v.getId()){
30 caseR.id.btcirc:
31 shape=0;
32 break;
33 caseR.id.btrect:
34 shape=1;
35 break;
36 }
37 if(rbfilled.isChecked()){
38 mySimpleView.setStyle(Style.FILL,shape);
39 }
40 if(rbstroke.isChecked()){
41 mySimpleView.setStyle(Style.STROKE,shape);
42 }
43 MyThreadmyThread=newMyThread(handler);
44 myThread.start();
45}
46finalHandlerhandler=newHandler(){
47 @Override
48 publicvoidhandleMessage(Messagemsg){
49 intstate=msg.getData().getInt("value");
50 if(state==VIEW_FRESH){
51 mySimpleView.invalidate();
52 }
53 }
54};
55}7.1.2SurfaceView类绘图程序框架
例7.4SurfaceView类绘图示例。
例7.4与例7.3执行的功能相同,如图7-2所示。
新建工程ex07_04,应用名为MySurfaceDrawApp,包名为cn.jxufe.zhangenhe,活动界面名为MySurfaceDrawAct。工程ex07_04包括源文件MySurfaceDrawAct.java、MySurfaceView.java、布局文件main.xml、颜色资源文件myguicolor.mxl和汉字字符串资源文件mystrings_hz.xml等。其中,文件myguicolor.mxl和mystrings_hz.xml与工程ex07_03中的同名文件相同。工程ex07_04的布局文件main.xml只是将工程ex07_03的布局文件main.xml中第52~58行换成以下代码:
1<cn.jxufe.zhangenhe.MySurfaceView
2android:id="@+id/myview"
3android:layout_width="480px"
4android:layout_height="400px"
5android:layout_x="0px"
6android:layout_y="160px"
7/>源文件MySurfaceView.java的代码如下所示:
1packagecn.jxufe.zhangenhe;
2
3importandroid.content.Context;
4importandroid.graphics.Canvas;
5importandroid.graphics.Color;
6importandroid.graphics.Paint;
7importandroid.graphics.Rect;
8importandroid.graphics.Paint.Style;
9importandroid.util.AttributeSet;
10importandroid.view.SurfaceHolder;
11importandroid.view.SurfaceView;
12
13publicclassMySurfaceViewextendsSurfaceView
14implementsSurfaceHolder.Callback,Runnable{
15 privateSurfaceHoldermyholder;
16 privateStylestyle=Style.STROKE;
17 privateintshape=0;
18 publicMySurfaceView(Contextcontext,AttributeSetattrs){
19 super(context,attrs);
20 myholder=this.getHolder();
21 myholder.addCallback(this);
22 }由于使用布局文件,因此必须使用第18~22行的构造方法。第20行得到SurfaceHolder对象myholder作为绘图容器。第21行注册myholder对象的回调方法,即当发生绘图对象大小变化、首次创建或被清除时Android系统将自动调用第24~26行、第28~30行或第32~33行的方法。当首次创建绘图对象时,创建并执行SurfaceView类的线程(第29行)。
31 @Override
32 publicvoidsurfaceDestroyed(SurfaceHolderholder){
33 }
34 @Override
35 publicvoidrun(){
36 try{
37 Thread.sleep(300);
38 }
39 catch(Exceptione){}
40 synchronized(myholder){
41 draw();
42 }
43 }
在线程中通过同步调用draw方法绘图(第40~42行)。
44 publicvoiddraw(){
45 Canvascanvas=myholder.lockCanvas();
46 canvas.drawColor(Color.DKGRAY);
47 Paintpaint=newPaint();
48 paint.setColor(Color.RED);
49 paint.setStyle(style);
50 switch(shape){
51 case0:
52 canvas.drawCircle(100,100,50,paint);
53 break;
54 case1:
55 Rectr=newRect(100,100,200,150);
56 canvas.drawRect(r,paint);
57 break;
58 }
59 myholder.unlockCanvasAndPost(canvas);
60 }
61 publicvoidsetStyle(Stylestyle,intshape){
62 this.style=style;
63 this.shape=shape;
64 }
65}
源文件MySurfaceDrawAct.java的内容如下所示:
1packagecn.jxufe.zhangenhe;
2
3importandroid.app.Activity;
4importandroid.graphics.Paint.Style;
5importandroid.os.Bundle;
6importandroid.view.View;
7importandroid.widget.RadioButton;
8
9publicclassMySurfaceDrawActextendsActivity{
10 publicstaticfinalintVIEW_FRESH=1;
11 privateRadioButtonrbfilled,rbstroke;
12 privateMySurfaceViewmySurfaceView;
13/**Calledwhentheactivityisfirstcreated.*/
14@Override
15publicvoidonCreate(BundlesavedInstanceState){
16super.onCreate(savedInstanceState);
17setContentView(R.layout.main);
18myInitGUI();
19}
20privatevoidmyInitGUI(){
21 mySurfaceView=(MySurfaceView)findViewById(R.id.myview);
22 rbfilled=(RadioButton)findViewById(R.id.rbfill);
23 rbstroke=(RadioButton)findViewById(R.id.rbstroke);
24}
25publicvoidmyShowMD(Viewv){
26 intshape=0;
27 switch(v.getId()){
28 caseR.id.btcirc:
29 shape=0;
30 break;
31 caseR.id.btrect:
32 shape=1;
33 break;
34 }
35 if(rbfilled.isChecked()){
36 mySurfaceView.setStyle(Style.FILL,shape);
37 }
38 if(rbstroke.isChecked()){
39 mySurfaceView.setStyle(Style.STROKE,shape);
40 }
41 newThread(mySurfaceView).start();
42}
43}
7.1.3基本图形与字符串
Android系统中常用的基本绘图方法有以下几种:
(1)画点。画点方法有三种,即:
● publicvoiddrawPoint(floatx,floaty,Paintpaint),在点(x,y)使用paint画笔绘一个单点。
● publicvoiddrawPoints(float[]pts,intoffset,intcount,Paintpaint),使用paint画笔绘制数组pts中的点列,offset指定跳过开始的点数,count指定绘制的总点数。pts的结构为
[x0,y0,x1,y1,…,xn,yn]。
● publicvoiddrawPoints(float[]pts,Paintpaint),使用画笔paint绘制数组pts中的所有点。
(2)画线。画线方法有三种,即:
● publicvoiddrawLine(floatstartX,floatstartY,floatstopX,floatstopY,Paintpaint),使用画笔paint从起点(startX,startY)画到终点(stopX,stopY)。
● publicvoiddrawLines(float[]pts,Paintpaint)。
● publicvoiddrawLines(float[]pts,intoffset,intcount,Paintpaint)。
上面这两种方法使用paint画笔以数组pts中的点为顶点画线,offset指定跳过开始的点数,count指定绘制的点数。pts的结构为[x0,y0,x1,y1,…,xn,yn],每四个数值组成一条线,即[x0,y0,x1,y1]为第一条线的起止点,[x2,y2,x3,y3]为第二条线的起止点。
(3)画复杂图形。
● publicvoiddrawPath(Pathpath,Paintpaint),使用画笔paint按path指定的绘制路线绘制图形。
(4)画圆。
● publicvoiddrawCircle(floatcx,flaotcy,floatradius,Paintpaint),使用画笔paint绘制圆心在(cx,cy)、半径为radius的圆。
(5)画椭圆。
● publicvoiddrawOval(RectFoval,Paintpaint),使用画笔paint绘制内接于矩形oval的椭圆。
(6)画矩形。● publicvoiddrwaRect(floatleft,floattop,floatright,floatbottom,Paintpaint)。
● publicvoiddrawRect(RectFrect,Paintpaint)。
● publicvoiddrawRect(Rectr,Paintpaint)。
使用画笔paint绘制矩形时,其中矩形的左上角为(left,top),右下角为(right,bottom),RectF和Rect类的对象含义相同,都包含矩形的左上角和右下角的点的坐标值,可以调用width或height方法得到矩形的宽和高。
(7)画圆角矩形。
● publicvoiddrawRoundRect(RectFrect,floatrx,floatry,Paintpaint),使用画笔paint绘制圆角矩形,rx和ry指定圆角区域的X和Y轴方向的半径。
(8)字符串。绘制字符串的方法有六种,即:
● publicvoiddrawText(Stringtext,floatx,floaty,Paintpaint)。
● publicvoiddrawText(CharSequencetext,intstart,intend,floatx,floaty,Paintpaint)。
● publicvoiddrawText(Stringtext,intstart,intend,floatx,floaty,Paintpaint)。
● publicvoiddrawText(char[]text,intindex,intcount,floatx,floaty,Paintpaint)。
● publicvoiddrawTextOnPath(Stringtext,Pathpath,floathOffset,floatvOffset,Paintpaint)。● publicvoiddrawTextOnPath(char[]text,intindex,intcount,Pathpath,floathOffset,floatvOffset,Paintpaint)。
上述绘制字符串方法中,点(x,y)表示绘图的起点坐标,start和end表示绘图的字符串中的起止字符位置,index和count分别表示字符串中要绘制的字符的起始位置和绘制字符的个数,path表示字符串绘制的路线。hOffset和vOffset分别表示字符串相对于绘制路线水平和垂直方向上偏移的位置。
在工程ex07_01至ex07_04中演示了画点、画圆和画矩形的方法,其他绘图方法的使用与这三种方法类似,这里不再举例。需要说明的是,除了上述列举的8类基本绘图方法外,在android.graphics.Canvas类中还有大量的绘图方法,请参考Android开发者手册。 7.2动画
7.2.1定时器动画
例7.5
定时器动画示例一。
新建工程ex07_05,包名为cn.jxfue.zhangzerui,应用名为MyTimerAnimApp,活动界面名为MyTimerAnimAct。工程ex07_05包括源文件MyTimerAnimAct.java、MySurface
View.java、布局文件main.xml、汉字字符串资源文件mystrings_hz.xml和颜色资源文件myguicolor.xml等。其中,文件myguicolor.xml与工程ex07_04中的同名文件内容相同。
工程ex07_05的执行结果如图7-3所示。图7-3工程ex07_05执行结果(注:小球有红、绿、蓝三色)在图7-3中,点击“演示”按钮,由红、绿、蓝三色组成的小球(图中以灰度显示)将从屏幕左侧向右侧滚动。点击“停止”按钮,停止滚动。
汉字字符串资源文件mystrings_hz.xml定义了两个汉字字符串“演示”和“停止”,其内容如下所示:
1<?xmlversion="1.0"encoding="utf-8"?>
2<resources>
3<stringname="strstart">演示</string>
4<stringname="strstop">停止</string>
5</resources>布局文件main.xml中定义了两个命令按钮和一个MySurfaceView控件,两个命令按钮的事件点击方法均为“myShowMD”,文件main.xml的内容如下所示:
1<?xmlversion="1.0"encoding="utf-8"?>
2<AbsoluteLayout
3android:id="@+id/widget35"
4android:layout_width="fill_parent"
5android:layout_height="fill_parent"
6xmlns:android="/apk/res/android"
7android:background="@drawable/darkgray"
8>
9<Button
10android:id="@+id/btstart"
11android:layout_width="120px"
12android:layout_height="60px"
13android:text="@string/strstart"
14android:layout_x="80px"
15android:layout_y="20px"
16android:onClick="myShowMD"
17>
18</Button>
19<Button
20android:id="@+id/btstop"
21android:layout_width="120px"
22android:layout_height="60px"
23android:text="@string/strstop"
24android:layout_x="280px"
25android:layout_y="20px"
26android:onClick="myShowMD"
27>
28</Button>
29<cn.jxufe.zhangzerui.MySurfaceView
30android:id="@+id/myview"
31android:layout_width="480px"
32android:layout_height="400px"
33android:layout_x="0px"
34android:layout_y="100px"
35/>
36</AbsoluteLayout>
源文件MySurfaceView.java负责绘图,其代码如下所示:
1packagecn.jxufe.zhangzerui;
2
3importandroid.content.Context;
4importandroid.graphics.Canvas;
5importandroid.graphics.Color;
6importandroid.graphics.Paint;
7importandroid.graphics.Paint.Style;
8importandroid.util.AttributeSet;
9importandroid.view.SurfaceHolder;
10importandroid.view.SurfaceView;
11
12publicclassMySurfaceViewextendsSurfaceView
13implementsSurfaceHolder.Callback,Runnable{
14 privateintlocx,dir;
15 privateSurfaceHoldermyholder;
16 publicMySurfaceView(Contextcontext,AttributeSetattrs){
17 super(context,attrs);
18 myholder=this.getHolder();
19 myholder.addCallback(this);
20 locx=100;
21 dir=0;
22 }
第14行定义了两个私有数据成员locx和dir。其中,locx用于表示图7-3中各小球围成的圆形的圆心横坐标,其取值为100~380;dir表示小球的颜色切换索引号,取值为0~2。第20~21行为这两个变量赋了初值100和0。
23 @Override
24 publicvoidsurfaceChanged(SurfaceHolderarg0,intarg1,
25 intarg2,intarg3){
26 }
27 @Override
28 publicvoidsurfaceCreated(SurfaceHolderholder){
29 newThread(this).start();
30 }
31 @Override
32 publicvoidsurfaceDestroyed(SurfaceHolderholder){
33 }
34 @Override
35 publicvoidrun(){
36 try{
37 Thread.sleep(300);
38 }
39 catch(Exceptione){}
40 synchronized(myholder){
41 draw();
42 }
43 }
44 publicvoiddraw(){
45 int[]color=newint[]{Color.BLUE,Color.RED,Color.GREEN};
46 Canvascanvas=myholder.lockCanvas();
47 canvas.drawColor(Color.DKGRAY);
48 Paintpaint=newPaint();
49 paint.setStyle(Style.FILL);
50 for(inti=0;i<360;i+=20){
51 paint.setColor(color[((i/20)%3+dir)%3]);
52 floatx0=(float)(locx+60*Math.sin(i*Math.PI/180));
53 floaty0=(float)(100+60*Math.cos(i*Math.PI/180));
54 canvas.drawCircle(x0,y0,10.0f,paint);
55 }
56 myholder.unlockCanvasAndPost(canvas);
57 }
58 publicvoidsetLocation(intlocx,intdir){
59 this.locx=locx;
60 this.dir=dir;
61 }
62}源文件MyTimerAnimAct.java创建了一个定时器,定时周期为0.2s,每个定时事件中请求刷新绘图,该文件的代码如下所示:
1packagecn.jxufe.zhangzerui;
2
3importjava.util.Timer;
4importjava.util.TimerTask;
5importandroid.app.Activity;
6importandroid.os.Bundle;
7importandroid.os.Handler;
8importandroid.os.Message;
9importandroid.view.View;
10
11publicclassMyTimerAnimActextendsActivity{
12 privateintlocx,dir;
13 privatebooleananimate=false;
14 privateMySurfaceViewmySurfaceView;
15@Override
16publicvoidonCreate(BundlesavedInstanceState){
17super.onCreate(savedInstanceState);
18setContentView(R.layout.main);
19myInitGUI();
20}
21privatevoidmyInitGUI(){
33 animate=false;
34 break;
35 }
36}
第27~36行为按钮“演示”和“停止”(见图7-3)的点击事件方法myShowMD。如果点击了“演示”按钮,则第30行将布尔型变量animate设为真;如果点击了“停止”按钮,则第33行将布尔型变量animate设为假。
37privatefinalTimertimer=newTimer();
38privateTimerTasktimerTask=newTimerTask(){
39 @Override
40 publicvoidrun(){
41 Messagemsg=newMessage();
42 if(animate){
43 msg.what=1;
44 handler.sendMessage(msg);
45 }
46 else{
47 msg.what=2;
48 handler.sendMessage(msg);
49 }
50 }
51};第37~51行为定义定时器和定时器任务,第25行打开定时器,定时周期为0.2s。关于定时器更详细的用法请参考第4.2.8节。每个定时事件到来后,如果变量animate为真,则发送消息1(第42~45行);如果变量animate为假,则发送消息2(第46~49行)。
52privateHandlerhandler=newHandler(){
53 @Override
54 publicvoidhandleMessage(Messagemsg){
55 intmsgID=msg.what;
56 switch(msgID){
57 case1:
58 locx=locx+10;
59 dir=dir+1;
60 if(locx>380){
61 locx=100;
62 }
63 if(dir>2){
64 dir=0;
65 }
66 mySurfaceView.setLocation(locx,dir);
67 newThread(mySurfaceView).start();
68 break;
69 case2:
70 break;
71 }
72 super.handleMessage(msg);
73 }
74};
75}
第52行的handler对象接收消息,如果消息为1,则更新locx和dir的值(第58~65行)。通过调用mySurfaceView对象的setLocation方法可设置绘图用的locx和dir。第67行为mySurfaceView开启一个新的线程,该线程启动新的绘图。
工程ex07_05的运行过程如框图7-4所示。图7-4工程ex07_05执行框图
例7.6
定时器动画示例二。
新建工程ex07_06,包名为cn.jxufe.jiaxiaotian,应用名为MyTimerAnimApp,活动界面名为MyTimerAnimAct。工程ex07_06包括源文件MyTimerAnimAct.java、MySurfaceView.java、布局文件main.xml、汉字字符串资源文件mystrings_hz.xm
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 演讲技巧口才15篇
- 关于参观类实习报告集锦9篇
- 药物流行病学杂志稿约
- “三全育人”视域下药理学实验课程思政建设探究
- 2024-2025学年高中数学 第1章 导数及其应用 1.2 导数的计算 1.2.1 1.2.2 基本初等函数的导数公式及导数的运算法则(二)(教师用书)教学实录 新人教A版选修2-2
- 励志演讲稿15篇
- 第11课 元朝的统治2023-2024学年七年级下册历史同步教学实录
- 2024-2025学年高中语文 第六单元 二 非攻教学实录8 新人教版选修《先秦诸子选读》
- 《电机拖动》-公开课件
- 基于智能硬件和社区服务升级的租房与智慧社区共享平台18
- 2023年7月黑龙江高中学业水平合格性考试历史试卷真题(含答案详解)
- 口腔医院年终总结报告
- 3度房室传导阻滞的护理
- 护理疑难病例讨论造瘘
- 数字孪生技术与MES系统的融合
- 人才梯队(人才库、人才盘点)建设方案
- 全国城市车牌代码一览表
- 小区物业弱电维护方案
- 典型地铁突发事件应急管理案例分析上海地铁碰撞事故
- 广西柳州市2023-2024学年四年级上学期期末考试语文试卷
- 手术室护理实践指南术中低体温预防
评论
0/150
提交评论