




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第7章Android圖形與動畫7.1繪圖
7.2動畫
7.3小結(jié)
7.1繪圖
7.1.1View類繪圖程序框架
借助View類繪圖,需要在View類的onDraw方法添加繪圖語句,然后在應用程序中顯示該View視圖。如果只是單純地繪制幾個圖形,Android系統(tǒng)會管理View視圖的顯示刷新工作,而程序員無需編寫刷新代碼,如例7.1所示。
例7.1View類簡單繪圖程序示例。
例7.1的運行結(jié)果如圖7-1所示,即顯示一個填充圓和圓圈。圖7-1例7.1運行結(jié)果(填充圓和圓圈為紅色)新建工程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類的構(gòu)造函數(shù)。
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的內(nèi)容如下所示:
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方法是不變的即繪制的是靜態(tài)圖形,這時的應用程序無需程序員編寫顯示刷新代碼,即無需調(diào)用invalidate方法。例7.2給出了一種單線程實現(xiàn)的View類繪圖操作,需要程序員編寫顯示刷新代碼,例7.2的執(zhí)行結(jié)果如圖7-2所示。圖7-2例7.2執(zhí)行結(jié)果漢字字符串資源文件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的代碼如下所示,重點需要關(guān)注第52~58行關(guān)于自定義的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中的同名文件的區(qū)別。
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行的構(gòu)造方法,其中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行根據(jù)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布局文件的內(nèi)容。
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執(zhí)行的結(jié)果與例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中同名文件的內(nèi)容完全相同,這里不再贅述。文件MyThread.java的內(nèi)容如下所示:
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的內(nèi)容如下所示,重點分析與工程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執(zhí)行的功能相同,如圖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行的構(gòu)造方法。第20行得到SurfaceHolder對象myholder作為繪圖容器。第21行注冊myholder對象的回調(diào)方法,即當發(fā)生繪圖對象大小變化、首次創(chuàng)建或被清除時Android系統(tǒng)將自動調(diào)用第24~26行、第28~30行或第32~33行的方法。當首次創(chuàng)建繪圖對象時,創(chuàng)建并執(zhí)行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 }
在線程中通過同步調(diào)用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的內(nèi)容如下所示:
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系統(tǒng)中常用的基本繪圖方法有以下幾種:
(1)畫點。畫點方法有三種,即:
●?publicvoiddrawPoint(floatx,floaty,Paintpaint),在點(x,y)使用paint畫筆繪一個單點。
●?publicvoiddrawPoints(float[]pts,intoffset,intcount,Paintpaint),使用paint畫筆繪制數(shù)組pts中的點列,offset指定跳過開始的點數(shù),count指定繪制的總點數(shù)。pts的結(jié)構(gòu)為
[x0,y0,x1,y1,…,xn,yn]。
●?publicvoiddrawPoints(float[]pts,Paintpaint),使用畫筆paint繪制數(shù)組pts中的所有點。
(2)畫線。畫線方法有三種,即:
●?publicvoiddrawLine(floatstartX,floatstartY,floatstopX,floatstopY,Paintpaint),使用畫筆paint從起點(startX,startY)畫到終點(stopX,stopY)。
●?publicvoiddrawLines(float[]pts,Paintpaint)。
●?publicvoiddrawLines(float[]pts,intoffset,intcount,Paintpaint)。
上面這兩種方法使用paint畫筆以數(shù)組pts中的點為頂點畫線,offset指定跳過開始的點數(shù),count指定繪制的點數(shù)。pts的結(jié)構(gòu)為[x0,y0,x1,y1,…,xn,yn],每四個數(shù)值組成一條線,即[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繪制內(nèi)接于矩形oval的橢圓。
(6)畫矩形?!?publicvoiddrwaRect(floatleft,floattop,floatright,floatbottom,Paintpaint)。
●?publicvoiddrawRect(RectFrect,Paintpaint)。
●?publicvoiddrawRect(Rectr,Paintpaint)。
使用畫筆paint繪制矩形時,其中矩形的左上角為(left,top),右下角為(right,bottom),RectF和Rect類的對象含義相同,都包含矩形的左上角和右下角的點的坐標值,可以調(diào)用width或height方法得到矩形的寬和高。
(7)畫圓角矩形。
●?publicvoiddrawRoundRect(RectFrect,floatrx,floatry,Paintpaint),使用畫筆paint繪制圓角矩形,rx和ry指定圓角區(qū)域的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分別表示字符串中要繪制的字符的起始位置和繪制字符的個數(shù),path表示字符串繪制的路線。hOffset和vOffset分別表示字符串相對于繪制路線水平和垂直方向上偏移的位置。
在工程ex07_01至ex07_04中演示了畫點、畫圓和畫矩形的方法,其他繪圖方法的使用與這三種方法類似,這里不再舉例。需要說明的是,除了上述列舉的8類基本繪圖方法外,在android.graphics.Canvas類中還有大量的繪圖方法,請參考Android開發(fā)者手冊。 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中的同名文件內(nèi)容相同。
工程ex07_05的執(zhí)行結(jié)果如圖7-3所示。圖7-3工程ex07_05執(zhí)行結(jié)果(注:小球有紅、綠、藍三色)在圖7-3中,點擊“演示”按鈕,由紅、綠、藍三色組成的小球(圖中以灰度顯示)將從屏幕左側(cè)向右側(cè)滾動。點擊“停止”按鈕,停止?jié)L動。
漢字字符串資源文件mystrings_hz.xml定義了兩個漢字字符串“演示”和“停止”,其內(nèi)容如下所示:
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的內(nèi)容如下所示:
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行定義了兩個私有數(shù)據(jù)成員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創(chuàng)建了一個定時器,定時周期為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。關(guān)于定時器更詳細的用法請參考第4.2.8節(jié)。每個定時事件到來后,如果變量animate為真,則發(fā)送消息1(第42~45行);如果變量animate為假,則發(fā)送消息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行)。通過調(diào)用mySurfaceView對象的setLocation方法可設置繪圖用的locx和dir。第67行為mySurfaceView開啟一個新的線程,該線程啟動新的繪圖。
工程ex07_05的運行過程如框圖7-4所示。圖7-4工程ex07_05執(zhí)行框圖
例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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 山西運城農(nóng)業(yè)職業(yè)技術(shù)學院《四史》2023-2024學年第二學期期末試卷
- 上海市普陀區(qū)2024-2025學年高三1月單科質(zhì)檢英語試題理試題含解析
- 上海中醫(yī)藥大學《醫(yī)學生物化學與分子生物學》2023-2024學年第二學期期末試卷
- 呂梁師范高等??茖W?!督y(tǒng)計學》2023-2024學年第一學期期末試卷
- 上海應用技術(shù)大學《全科醫(yī)學》2023-2024學年第二學期期末試卷
- 2025年心理咨詢師考試試題及答案
- 2025年心理學專業(yè)研究生入學考試試題及答案
- 2025年藥學專業(yè)畢業(yè)生資格考試試題及答案
- 2025年司法考試模擬試卷及答案
- 2025年市場營銷專業(yè)考試試題及答案揭秘
- 常州施工招標開標清標評標報告
- 第十五屆運動會場館醫(yī)療保障工作方案
- 生理衛(wèi)生教學課件青春期男生性教育走向成熟
- 體外診斷試劑標準品、校準品、質(zhì)控品
- GB/T 3452.4-2020液壓氣動用O形橡膠密封圈第4部分:抗擠壓環(huán)(擋環(huán))
- 王力宏-緣分一道橋-歌詞
- (完整版)建筑施工技術(shù)規(guī)范
- 高校電子課件:現(xiàn)代管理學基礎(第三版)
- 《藥物學》課程教學大綱
- 艾滋病感染孕產(chǎn)婦所生兒童艾滋病早期診斷與抗體檢測流程圖
- 修改版絲竹相和
評論
0/150
提交評論