您的位置:首页 > 移动开发 > Android开发

Android应用开发基础篇(8)-----SurfaceView

2012-02-25 19:55 399 查看
一、概述

SurfaceView也是一个用来画图的部件,不过由于它的效率比较高,因此一般多用在游戏编程中,在摄像头编程中也会用到,还有它和View比较大的不同是它可以在非UI线程里画图。下面的实现中会提到使用SurfaceView来画图需要注意的几个地方。

二、要求

会使用SurfaceView来画图。

三、实现

新建工程MySurface,修改/res/layout/main.xml文件,在里面添加一个Button和一个SurfaceView,完整的main.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<Button
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="画线"
/>

<SurfaceView
android:id="@+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

</LinearLayout>


修改MySurfaceActivity.java文件,主要实现Button的监听和SurfaceHolder.Callback的接口,完整的内容如下:

package com.nan.surface;

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.SurfaceView;
import android.view.View;
import android.widget.Button;

public class MySurfaceActivity extends Activity
{
private int OldX = 0;
private int OldY = 0;
private Button mButton = null;
private SurfaceView mSurfaceView = null;
private SurfaceHolder mSurfaceHolder = null;
private Paint mPaint = null;

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mButton = (Button)findViewById(R.id.button);
mSurfaceView = (SurfaceView)findViewById(R.id.surface);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(new MyHolder());

mPaint = new Paint();
//画笔的颜色
mPaint.setColor(Color.RED);
//画笔的粗细
mPaint.setStrokeWidth(10.0f);
//按钮监听
mButton.setOnClickListener(new View.OnClickListener()
{

public void onClick(View v)
{
// TODO Auto-generated method stub
//锁定整个SurfaceView
Canvas mCanvas = mSurfaceHolder.lockCanvas();
mCanvas.drawLine(OldX, OldY, OldX+10, OldY+10, mPaint);
//横坐标增加
OldX = OldX + 10;
//纵坐标增加
OldY = OldY + 10;
// 绘制完成,释放画布,提交修改
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
//重新锁一次
//mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
//mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
});
}

//定义一个类,实现Callback接口
public class MyHolder implements SurfaceHolder.Callback
{

public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
// TODO Auto-generated method stub
//add your code
}

public void surfaceCreated(SurfaceHolder holder)
{
// TODO Auto-generated method stub
//add your code
}

public void surfaceDestroyed(SurfaceHolder holder)
{
// TODO Auto-generated method stub
//add your code
}

}

}


此时运行该程序,并点击几下“画线”按钮,效果如下所示:



可以看到,画出来的线是断断续续的,把上面程序的第58,59行的注释去掉,再运行一次,效果如下:



可以看到,线已经没有断开的现象了。

还有一点需要注意的是,如果希望程序在后台运行时还能画图且不报程序出错的问题,就要修改成以下这样的形式:

//锁定整个SurfaceView
Canvas mCanvas = mSurfaceHolder.lockCanvas();
try
{
if(mCanvas!=null)
{
mCanvas.drawLine(OldX, OldY, OldX+10, OldY+10, mPaint);
//横坐标增加
OldX = OldX + 10;
//纵坐标增加
OldY = OldY + 10;
//绘制完成,释放画布,提交修改
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(mCanvas!=null)
{
//重新锁一次
mSurfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}


再运行,效果同第2幅图的一样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐