引用:http://www.oschina.net/code/snippet_54100_1423
SurfaceView 由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,网上介绍 SurfaceView的用法有很多,写法也层出不同,例如继承SurfaceView类,或者继承SurfaceHolder.Callback类等,这个可以根据功能实际需要自己选择,我这里就直接在普通的用户界面调用SurfaceHolder的lockCanvas和 unlockCanvasAndPost。
对比下面的第二、三两图,三图用.lockCanvas(null),而二图用.lockCanvas(new Rect(oldX, 0, oldX + length, getWindowManager().getDefaultDisplay().getHeight())),对比一下两个效果,由于二图是按指定Rect绘画,所以效率会比三图的全控件绘画高些,并且在清屏之后 (canvas.drawColor(Color.BLACK))不会留有上次绘画的残留。
[代码] main.xml
01 |
<? xml version = "1.0" encoding = "utf-8" ?> |
02 |
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" |
03 |
android:layout_width = "fill_parent" android:layout_height = "fill_parent" |
04 |
android:orientation = "vertical" > |
06 |
< LinearLayout android:id = "@+id/LinearLayout01" |
07 |
android:layout_width = "wrap_content" android:layout_height = "wrap_content" > |
08 |
< Button android:id = "@+id/Button01" android:layout_width = "wrap_content" |
09 |
android:layout_height = "wrap_content" android:text = "简单绘画" ></ Button > |
10 |
< Button android:id = "@+id/Button02" android:layout_width = "wrap_content" |
11 |
android:layout_height = "wrap_content" android:text = "定时器绘画" ></ Button > |
13 |
< SurfaceView android:id = "@+id/SurfaceView01" |
14 |
android:layout_width = "fill_parent" android:layout_height = "fill_parent" ></ SurfaceView > |
[代码] TestSurfaceView.java
001 |
package com.testSurfaceView; |
003 |
import java.util.Timer; |
004 |
import java.util.TimerTask; |
006 |
import android.app.Activity; |
007 |
import android.graphics.Canvas; |
008 |
import android.graphics.Color; |
009 |
import android.graphics.Paint; |
010 |
import android.graphics.Rect; |
011 |
import android.os.Bundle; |
012 |
import android.util.Log; |
013 |
import android.view.SurfaceHolder; |
014 |
import android.view.SurfaceView; |
015 |
import android.view.View; |
016 |
import android.widget.Button; |
018 |
public class TestSurfaceView extends Activity { |
019 |
/** Called when the activity is first created. */ |
020 |
Button btnSimpleDraw, btnTimerDraw; |
024 |
private Timer mTimer; |
025 |
private MyTimerTask mTimerTask; |
032 |
public void onCreate(Bundle savedInstanceState) { |
033 |
super .onCreate(savedInstanceState); |
034 |
setContentView(R.layout.main); |
036 |
btnSimpleDraw = (Button) this .findViewById(R.id.Button01); |
037 |
btnTimerDraw = (Button) this .findViewById(R.id.Button02); |
038 |
btnSimpleDraw.setOnClickListener( new ClickEvent()); |
039 |
btnTimerDraw.setOnClickListener( new ClickEvent()); |
040 |
sfv = (SurfaceView) this .findViewById(R.id.SurfaceView01); |
041 |
sfh = sfv.getHolder(); |
044 |
mTimer = new Timer(); |
045 |
mTimerTask = new MyTimerTask(); |
048 |
centerY = (getWindowManager().getDefaultDisplay().getHeight() - sfv |
050 |
Y_axis = new int [getWindowManager().getDefaultDisplay().getWidth()]; |
051 |
for ( int i = 1 ; i < Y_axis.length; i++) { |
052 |
Y_axis[i - 1 ] = centerY |
053 |
- ( int ) ( 100 * Math.sin(i * 2 * Math.PI / 180 )); |
057 |
class ClickEvent implements View.OnClickListener { |
060 |
public void onClick(View v) { |
062 |
if (v == btnSimpleDraw) { |
063 |
SimpleDraw(Y_axis.length- 1 ); |
065 |
} else if (v == btnTimerDraw) { |
067 |
mTimer.schedule(mTimerTask, 0 , 5 ); |
074 |
class MyTimerTask extends TimerTask { |
078 |
SimpleDraw(currentX); |
080 |
if (currentX == Y_axis.length - 1 ) { |
092 |
void SimpleDraw( int length) { |
095 |
Canvas canvas = sfh.lockCanvas( new Rect(oldX, 0 , oldX + length, |
096 |
getWindowManager().getDefaultDisplay().getHeight())); |
098 |
String.valueOf(oldX) + "," + String.valueOf(oldX + length)); |
100 |
Paint mPaint = new Paint(); |
101 |
mPaint.setColor(Color.GREEN); |
102 |
mPaint.setStrokeWidth( 2 ); |
105 |
for ( int i = oldX + 1 ; i < length; i++) { |
107 |
canvas.drawLine(oldX, oldY, i, y, mPaint); |
111 |
sfh.unlockCanvasAndPost(canvas); |
115 |
Canvas canvas = sfh.lockCanvas( null ); |
116 |
canvas.drawColor(Color.BLACK); |
117 |
sfh.unlockCanvasAndPost(canvas); |