A drawing is made in the previous definition view. However, the drawing mechanism for view has the following drawbacks:
1, view lacks double buffering mechanism.
2. When the program needs to update the image on the view, the program must redraw the entire picture displayed on the view.
3. The new thread cannot update the view component directly.
Because the view has the above flaw. Therefore, in the game development generally uses the Surfaceview to draw, the Surfaceview usually will use with the Surfaceholder union. The surfaceholder is used to draw on the surfaceview associated with it, and the Getholder () method of Surfaceview calls the Surfaceview associated Surfaceholder.
Surfaceholder provides methods such as the following to get a canvas object:
1. Canvas Lockcanvas (): Lock the entire Surfaceview object to get the canvas on that surface.
2. Canvas Lockcanvas (rect dirty): Locks the area of the rect on the Surfaceview. Get the canvas on the surface.
Two methods return the same canvas, but the second method simply refreshes the circled area, and after the canvas finishes drawing, it releases the canvas and commits the changes using the Unlockcanvasandpost (canvas) method. After calling Surfaceholder's Unlockcanvasandpost method. The graph drawn before the method is still buffered. The area locked by the next Lockcanvas () method may "obscure" it.
Package Com.example.erweimatest;import Android.app.activity;import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.rect;import Android.os.bundle;import android.view.MotionEvent; Import Android.view.surfaceholder;import Android.view.surfaceholder.callback;import Android.view.SurfaceView; Import Android.view.view;import Android.view.view.ontouchlistener;public class Surfaceviewtest extends Activity { Private Surfaceholder holder;private paint paint; @Overrideprotected void OnCreate (Bundle savedinstancestate) { Super.oncreate (Savedinstancestate), Setcontentview (r.layout.main);p aint = new paint (); Surfaceview surface = (Surfaceview) Findviewbyid (r.id.show);//Initialize Surfaceholder object holder = Surface.getholder (); Holder.addcallback (New Callback () {@Overridepublic void surfacedestroyed (Surfaceholder holder) {} @Overridepublic void Surfacecreated (Surfaceholder holder) {//Lock entire SURFACEviewcanvas canvas = Holder.lockcanvas ();//Draw background Bitmap back = Bitmapfactory.decoderesource ( SurfaceViewTest.this.getResources (), r.drawable.bg);//Draw Background canvas.drawbitmap (back, 0, 0, NULL);//Draw complete. Release the canvas, commit the change holder.unlockcanvasandpost (canvas);//Lock once again, "persist" the last drawing// This time Lockcanvas will obscure the last Lockcanvasholder.lockcanvas (new Rect (0, 0, 0, 0)); holder.unlockcanvasandpost (canvas);} @Overridepublic void Surfacechanged (surfaceholder holder, int format, int width,int height) {//TODO auto-generated method {{Surface.setontouchlistener}}); {new Ontouchlistener () {@Overridepublic Boolean onTouch (View V, motionevent event) { if (event.getaction () = = Motionevent.action_down) {int cx = (int) event.getx (); int cy = (int) event.gety ();// Lock the Surfaceview layout area, just update the local content canvas canvas = Holder.lockcanvas (New Rect (CX-50, CY-50, CX +, CY + 50));//Save Canvas Current state C Anvas.save ();//Rotate Canvas canvas.rotate ((), CX, CY);p Aint.setcolor (color.red);//Draw Red squares canvas.drawrect (cx-40, cy-40, CX, CY , paint);//Restore the canvas before the Save state Canvas.restore ();p aint.SetColor (Color.green);//Draw Green squares canvas.drawrect (CX, CY, CX + +, CY + +, paint);//Draw and release the canvas. Submit Changes Holder.unlockcanvasandpost (canvas);} return false;}});}}
Main.xml
<?xml version= "1.0" encoding= "Utf-8"?><linearlayout xmlns:android= "http://schemas.android.com/apk/res/android" android:orientation= "vertical" Android:layout_width= "Fill_parent" android:layout_height= "fill_parent" ><surfaceview android:id= "@+id/ Show "Android:layout_width=" Fill_parent "android:layout_height=" Fill_parent "/></linearlayout>
Execution effect:
It can be seen that the first drawing will be obscured by the second area, and the third drawing may obscure the area that is being drawn for the second time. But will not obscure the first area. Suppose that the second drawn area is obscured by the third area, and the graph drawn for the first time may be exposed.
An oscilloscope based on Surfaceview development:
Package Com.example.erweimatest;import Java.util.timer;import Java.util.timertask;import android.app.Activity; Import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.rect;import Android.os.bundle;import Android.view.surfaceholder;import Android.view.surfaceholder.callback;import Android.view.surfaceview;import Android.view.view;import Android.view.view.onclicklistener;import Android.widget.button;public class Showvawe extends Activity{private Surfaceholder holder;private Paint paint;final int HEIGHT = 320;final int WIDTH = 320;final int x_offset = 5;private int C x = x_offset;//The actual y-axis position int centery = HEIGHT/2; Timer timer = new timer (); TimerTask task = null; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate) ; Setcontentview (R.layout.activity_main); final Surfaceview surface = (Surfaceview) Findviewbyid (r.id.show);// Initialize the Surfaceholder object holder = Surface.getholder ();p aint = new paint ();p aint.SetColor (Color.green);p aint.setstrokewidth (3); Button sin = (button) Findviewbyid (R.id.sin); Button cos = (button) Findviewbyid (r.id.cos), Onclicklistener listener = (new Onclicklistener () {@Overridepublic void Oncl Ick (final View source) {drawback (holder); CX = x_offset;if (Task! = null) {Task.cancel ();} task = new TimerTask () {@Overridepublic void run () {int cy = Source.getid () = = R.id.sin? CenterY-(int) (* Math.sin ( CX-5) * 2 * math.pi/150): centery-(int) (+ * Math.Cos ((cx-5) * 2 * math.pi/150)); Canvas canvas = Holder.lockcanvas (New Rect (CX, Cy-2, cx+2, CY + 2)), Canvas.drawpoint (CX, CY, paint), CX ++;if (cx > WID TH) {task.cancel (); task = null;} Holder.unlockcanvasandpost (canvas);}}; Timer.schedule (Task, 0, 30);}); Sin.setonclicklistener (listener); Cos.setonclicklistener (listener); Holder.addcallback (new Callback () {@ overridepublic void surfacedestroyed (Surfaceholder holder) {//TODO auto-generated method stub} @Overridepublic void Surfacecreated (Surfaceholder holder) {//TODO auto-generated method stub} @Overridepublic void Surfacechanged (surfaceholder holder, int format, int width,int height) {/ /TODO auto-generated Method stub}}); private void drawback (Surfaceholder holder) {Canvas canvas = Holder.lockcanvas ();//Draw white background canvas.drawcolor (color.white ); Paint p = new paint ();p. SetColor (Color.Black);p. Setstrokewidth (2);//Draw Axis Canvas.drawline (X_offset, CenterY, WIDTH, CenterY, p); Canvas.drawline (X_offset, Max, X_offset, HEIGHT, p); holder.unlockcanvasandpost (canvas); Holder.lockcanvas (New Rect (0, 0, 0, 0)); holder.unlockcanvasandpost (canvas);}}
Activity_main.xml
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android "android:orientation=" vertical "android:layout_width=" fill_parent "android:layout_height=" Fill_parent " ><linearlayout android:orientation= "Horizontal" android:layout_width= "Fill_parent" android:layout_height= " Wrap_content "android:gravity=" center "><button android:id=" @+id/sin "android:layout_width=" Wrap_content " android:layout_height= "Wrap_content" android:text= "positive spin curve"/><button android:id= "@+id/cos" Android:layout_ Width= "Wrap_content" android:layout_height= "wrap_content" android:text= "Yu Yen curve"/></linearlayout>< Surfaceview android:id= "@+id/show" android:layout_width= "fill_parent" android:layout_height= "Fill_parent" Android: gravity= "Center"/></linearlayout>
Execution Result:
The program does not need to redraw the entire screen each time the program draws the current point on the Yu Yen wave. Surfaceholder only want to lock the current drawing point of the small range can be, the System Update screen only to update this range can be.
Android Rookie's growth note (--surfaceview) use