廢話少說,言歸正傳,下面用幾個例子說明surfaceview的使用。
(一) 基本功能:用SurfaceView顯示一副背景圖片。 運行後的效果很簡單,就是在屏幕上顯示一副圖片。
- package com.pushBox;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.os.Bundle;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- public class PushBoxActivity extends Activity {
- //歡迎界面
- WelcomeView welcomeView = null;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //顯示歡迎界面
- welcomeView = new WelcomeView( this );
- setContentView( welcomeView );
- }
- //內部類,歡迎界面
- class WelcomeView extends SurfaceView implements SurfaceHolder.Callback
- {
- private SurfaceHolder holder;
- private WelcomeViewDrawThread welcomeViewDrawThread;
- //背景圖片,大小640 * 480
- Bitmap background;
- //圖片顯示的位置
- int backgroundX = 0;
- int backgroundY = 0;
- public WelcomeView( Context context )
- {
- super( context );
- holder = this.getHolder();
- holder.addCallback( this );
- background = BitmapFactory.decodeResource( getResources(), R.drawable.background );
- //創建一個繪圖線程
- welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder );
- }
- //自定義的繪圖函數,具體的繪圖在這裏完成
- public void onDraw( Canvas c )
- {
- c.drawBitmap( background, backgroundX, backgroundY, null );
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- // TODO Auto-generated method stub
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- // TODO Auto-generated method stub
- //啓動繪圖線程
- welcomeViewDrawThread.setFlag( true );
- welcomeViewDrawThread.start();
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- // TODO Auto-generated method stub
- welcomeViewDrawThread.setFlag( false );
- }
- }
- //內部類,歡迎界面的繪圖線程
- class WelcomeViewDrawThread extends Thread
- {
- private WelcomeView welcomeView;
- private SurfaceHolder holder;
- private boolean isRun;
- private int sleepSpan = 200;
- public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder )
- {
- this.welcomeView = welcomeView;
- this.holder = holder;
- isRun = true;
- }
- public void setFlag( boolean flag )
- {
- isRun = flag;
- }
- @Override
- public void run() {
- // TODO Auto-generated method stub
- while( isRun )
- {
- Canvas c = null;
- try
- {
- c = holder.lockCanvas();
- synchronized( holder )
- {
- //調用繪圖函數
- welcomeView.onDraw( c );
- }
- }finally
- {
- if( c != null )
- {
- holder.unlockCanvasAndPost( c );
- }
- }
- try{
- //睡眠200毫秒
- Thread.sleep( sleepSpan );
- }
- catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- }
- }
package com.pushBox;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class PushBoxActivity extends Activity {
//歡迎界面
WelcomeView welcomeView = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//顯示歡迎界面
welcomeView = new WelcomeView( this );
setContentView( welcomeView );
}
//內部類,歡迎界面
class WelcomeView extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder holder;
private WelcomeViewDrawThread welcomeViewDrawThread;
//背景圖片,大小640 * 480
Bitmap background;
//圖片顯示的位置
int backgroundX = 0;
int backgroundY = 0;
public WelcomeView( Context context )
{
super( context );
holder = this.getHolder();
holder.addCallback( this );
background = BitmapFactory.decodeResource( getResources(), R.drawable.background );
//創建一個繪圖線程
welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder );
}
//自定義的繪圖函數,具體的繪圖在這裏完成
public void onDraw( Canvas c )
{
c.drawBitmap( background, backgroundX, backgroundY, null );
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
//啓動繪圖線程
welcomeViewDrawThread.setFlag( true );
welcomeViewDrawThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
welcomeViewDrawThread.setFlag( false );
}
}
//內部類,歡迎界面的繪圖線程
class WelcomeViewDrawThread extends Thread
{
private WelcomeView welcomeView;
private SurfaceHolder holder;
private boolean isRun;
private int sleepSpan = 200;
public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder )
{
this.welcomeView = welcomeView;
this.holder = holder;
isRun = true;
}
public void setFlag( boolean flag )
{
isRun = flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
while( isRun )
{
Canvas c = null;
try
{
c = holder.lockCanvas();
synchronized( holder )
{
//調用繪圖函數
welcomeView.onDraw( c );
}
}finally
{
if( c != null )
{
holder.unlockCanvasAndPost( c );
}
}
try{
//睡眠200毫秒
Thread.sleep( sleepSpan );
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
}
(二) 初露鋒芒:用SurfaceView顯示一個動態打開的門。運行後的效果,左右兩扇門緩緩打開。
如果只用SurfaceView顯示一副背景圖片,那絕對是“大炮打蚊子”------大材小用。從主線程中拉出一個單獨的線程,就是爲了處理動態效果。這裏具體實現的時候有兩個線程:welcomeViewGoThread和welcomeViewDrawThread。welcomeViewGoThread只負責修改圖片顯示的座標,welcomeViewDrawThread負責在具體的位置顯示圖片。這種進一步分離,使得各模塊的功能更加獨立和明確。
- package com.pushBox;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.os.Bundle;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- public class PushBoxActivity extends Activity {
- //歡迎界面
- WelcomeView welcomeView = null;
- //歡迎界面的動畫線程
- WelcomeViewGoThread welcomeViewGoThread = null;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //顯示歡迎界面
- welcomeView = new WelcomeView( this );
- setContentView( welcomeView );
- welcomeViewGoThread = new WelcomeViewGoThread( welcomeView );
- //啓動動畫線程
- welcomeViewGoThread.start();
- }
- //內部類,歡迎界面
- class WelcomeView extends SurfaceView implements SurfaceHolder.Callback
- {
- private SurfaceHolder holder;
- private WelcomeViewDrawThread welcomeViewDrawThread;
- //背景圖片,大小640 * 480
- Bitmap background;
- //左邊的木門,大小180 * 450
- Bitmap leftWood;
- Bitmap rightWood;
- //圖片顯示的位置
- int backgroundX = 0;
- int backgroundY = 0;
- int leftWoodX = 10;
- int leftWoodY = 15;
- int rightWoodX = 150;
- int rightWoodY = 15;
- public WelcomeView( Context context )
- {
- super( context );
- holder = this.getHolder();
- holder.addCallback( this );
- background = BitmapFactory.decodeResource( getResources(), R.drawable.background );
- leftWood = BitmapFactory.decodeResource( getResources(), R.drawable.image33 );
- rightWood = BitmapFactory.decodeResource( getResources(), R.drawable.image3 );
- //創建一個繪圖線程
- welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder );
- }
- //自定義的繪圖函數,具體的繪圖在這裏完成
- public void onDraw( Canvas c )
- {
- c.drawBitmap( background, backgroundX, backgroundY, null );
- c.drawBitmap( leftWood, leftWoodX, leftWoodY, null );
- c.drawBitmap( rightWood, rightWoodX, rightWoodY, null );
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- // TODO Auto-generated method stub
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- // TODO Auto-generated method stub
- //啓動繪圖線程
- welcomeViewDrawThread.setFlag( true );
- welcomeViewDrawThread.start();
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- // TODO Auto-generated method stub
- welcomeViewDrawThread.setFlag( false );
- }
- }
- //內部類,歡迎界面的動畫線程,只修改座標,不負責具體顯示
- class WelcomeViewGoThread extends Thread
- {
- private WelcomeView welcomeView;
- private int sleepSpan = 200;
- private boolean isRun;
- public WelcomeViewGoThread( WelcomeView welcomeView )
- {
- this.welcomeView = welcomeView;
- isRun = true;
- }
- public void setFlag( boolean flag )
- {
- isRun = flag;
- }
- @Override
- public void run() {
- // TODO Auto-generated method stub
- while( isRun )
- {
- // 修改木門座標
- welcomeView.leftWoodX -= 2;
- welcomeView.rightWoodX += 2;
- if( welcomeView.leftWoodX < -90 )
- {
- welcomeView.leftWoodX = 10;
- welcomeView.rightWoodX = 150;
- }
- try{
- //睡眠200毫秒
- Thread.sleep( sleepSpan );
- }
- catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- }
- //內部類,歡迎界面的繪圖線程
- class WelcomeViewDrawThread extends Thread
- {
- private WelcomeView welcomeView;
- private SurfaceHolder holder;
- private boolean isRun;
- private int sleepSpan = 200;
- public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder )
- {
- this.welcomeView = welcomeView;
- this.holder = holder;
- isRun = true;
- }
- public void setFlag( boolean flag )
- {
- isRun = flag;
- }
- @Override
- public void run() {
- // TODO Auto-generated method stub
- while( isRun )
- {
- Canvas c = null;
- try
- {
- c = holder.lockCanvas();
- synchronized( holder )
- {
- //調用繪圖函數
- welcomeView.onDraw( c );
- }
- }finally
- {
- if( c != null )
- {
- holder.unlockCanvasAndPost( c );
- }
- }
- try{
- //睡眠200毫秒
- Thread.sleep( sleepSpan );
- }
- catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- }
- }
package com.pushBox;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class PushBoxActivity extends Activity {
//歡迎界面
WelcomeView welcomeView = null;
//歡迎界面的動畫線程
WelcomeViewGoThread welcomeViewGoThread = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//顯示歡迎界面
welcomeView = new WelcomeView( this );
setContentView( welcomeView );
welcomeViewGoThread = new WelcomeViewGoThread( welcomeView );
//啓動動畫線程
welcomeViewGoThread.start();
}
//內部類,歡迎界面
class WelcomeView extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder holder;
private WelcomeViewDrawThread welcomeViewDrawThread;
//背景圖片,大小640 * 480
Bitmap background;
//左邊的木門,大小180 * 450
Bitmap leftWood;
Bitmap rightWood;
//圖片顯示的位置
int backgroundX = 0;
int backgroundY = 0;
int leftWoodX = 10;
int leftWoodY = 15;
int rightWoodX = 150;
int rightWoodY = 15;
public WelcomeView( Context context )
{
super( context );
holder = this.getHolder();
holder.addCallback( this );
background = BitmapFactory.decodeResource( getResources(), R.drawable.background );
leftWood = BitmapFactory.decodeResource( getResources(), R.drawable.image33 );
rightWood = BitmapFactory.decodeResource( getResources(), R.drawable.image3 );
//創建一個繪圖線程
welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder );
}
//自定義的繪圖函數,具體的繪圖在這裏完成
public void onDraw( Canvas c )
{
c.drawBitmap( background, backgroundX, backgroundY, null );
c.drawBitmap( leftWood, leftWoodX, leftWoodY, null );
c.drawBitmap( rightWood, rightWoodX, rightWoodY, null );
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
//啓動繪圖線程
welcomeViewDrawThread.setFlag( true );
welcomeViewDrawThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
welcomeViewDrawThread.setFlag( false );
}
}
//內部類,歡迎界面的動畫線程,只修改座標,不負責具體顯示
class WelcomeViewGoThread extends Thread
{
private WelcomeView welcomeView;
private int sleepSpan = 200;
private boolean isRun;
public WelcomeViewGoThread( WelcomeView welcomeView )
{
this.welcomeView = welcomeView;
isRun = true;
}
public void setFlag( boolean flag )
{
isRun = flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
while( isRun )
{
// 修改木門座標
welcomeView.leftWoodX -= 2;
welcomeView.rightWoodX += 2;
if( welcomeView.leftWoodX < -90 )
{
welcomeView.leftWoodX = 10;
welcomeView.rightWoodX = 150;
}
try{
//睡眠200毫秒
Thread.sleep( sleepSpan );
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
//內部類,歡迎界面的繪圖線程
class WelcomeViewDrawThread extends Thread
{
private WelcomeView welcomeView;
private SurfaceHolder holder;
private boolean isRun;
private int sleepSpan = 200;
public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder )
{
this.welcomeView = welcomeView;
this.holder = holder;
isRun = true;
}
public void setFlag( boolean flag )
{
isRun = flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
while( isRun )
{
Canvas c = null;
try
{
c = holder.lockCanvas();
synchronized( holder )
{
//調用繪圖函數
welcomeView.onDraw( c );
}
}finally
{
if( c != null )
{
holder.unlockCanvasAndPost( c );
}
}
try{
//睡眠200毫秒
Thread.sleep( sleepSpan );
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
}
(三) 脫胎換骨:修改程序框架。
上述的程序框架有問題,所有代碼都放在一個文件裏。下面要做的就是把相關的class都獨立出來。代碼改起來也很簡單,只要把幾個內部類單獨寫到一個文件即可。
(四) 重出江湖:用SurfaceView實現一個完整的歡迎界面