展会信息港展会大全

Android 画图类View与SurfaceView之学习
来源:互联网   发布日期:2015-10-13 07:40:49   浏览:2090次  

导读:在开发游戏开发中,android相应的提供了几个重要的模块:1、显示界面的视图: Android 提供 View 和 SurfaceView2、控制游戏整体结构: android 提供...

在开发游戏开发中,android相应的提供了几个重要的模块:

1、显示界面的视图: Android 提供 View 和 SurfaceView

2、控制游戏整体结构: android 提供 Activity

3、逻辑控制类:专门用于处理游戏的逻辑计算

4、处理游戏界面与用户交互事件 : 利用 View 类提供的 onKeyDown onKeyUp onTounchEvent等方法

我们这里简单熟悉一下如何在视图上画东西。

1、View 类: android.view.View

View 是Android中的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘画的画布,这个画布 可以进行任何扩展。

任何一个View类都只需要重写onDraw方法来实现界面显示,任何一个View都只需要重写 OnDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本或位图。

Android 中有个重要的东东: Android UI 线程

在这里 http://blog.csdn.net/andyhuabing/article/details/11921887 有对其简要精典的介绍及注意点,这里就不再重复说明了。

这里来个简单例子说明一下View的用法,利用线程变更显示颜色,通过上下左右移动矩形

TestView.java 类如下:

[java]

package com.example.testondraw;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.view.View;

/**

* View 是Android中的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘画的画布,这个画布 可以进行任何扩展。

*

* 任何一个View类都只需要重写onDraw方法来实现界面显示。

*

*/

public class TestView extends View {

int miCount = 0;

int x = 10, y = 10;

public TestView(Context context) {

super(context);

}

@Override

protected void onDraw(Canvas canvas) {

if (miCount < 100)

{

miCount++;

}

else

{

miCount = 0;

}

//绘图

Paint mPaint = new Paint();

switch (miCount%4)

{

case 0:

mPaint.setColor(Color.BLUE);

break;

case 1:

mPaint.setColor(Color.GREEN);

break;

case 2:

mPaint.setColor(Color.RED);

break;

case 3:

mPaint.setColor(Color.YELLOW);

break;

default:

mPaint.setColor(Color.WHITE);

break;

}

// 绘制矩形

canvas.drawRect(x, y, x + 120, y + 80, mPaint);

}

}

如何在 Acitivty 使用呢?示例代码如下:

[java]

package com.example.testondraw;

import java.util.List;

import android.app.Activity;

import android.app.ActivityManager;

import android.content.Context;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.DisplayMetrics;

import android.util.Log;

import android.view.KeyEvent;

import android.view.Menu;

public class MainActivity extends Activity {

static final String TAG = "MainActivity";

private TestView mTestView = null;

private TestSurfaceView mTestSurfaceView = null;

private int mWidth = 0, mHeight = 0;

private MyHandler mHandler = new MyHandler();

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

initView();

startTestView();

// setContentView(R.layout.main);

}

void initView() {

// 使用自定义的View

mTestView = new TestView(this);

setContentView(mTestView);

DisplayMetrics dm = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(dm);

mWidth = dm.widthPixels;

mHeight = dm.heightPixels;

Log.i(TAG, "Display Metrics width:" + mWidth + " mHeight:" + mHeight);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

void startTestView() {

Thread th = new Thread(new Runnable() {

@Override

public void run() {

while (!Thread.currentThread().isInterrupted()) {

// 使用postInvalidate可以直接在线程中更新界面

// mTestView.postInvalidate();

// 使用发消息给UI线程

Message msg = Message.obtain();

msg.what = 1;

mHandler.sendMessage(msg);

try {

Thread.sleep(100);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}

}

});

th.start();

}

class MyHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case 1:

mTestView.invalidate();

break;

default:

break;

}

super.handleMessage(msg);

}

}

public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {

switch (keyCode) {

case KeyEvent.KEYCODE_DPAD_DOWN:

if (mTestView.y >= mHeight)

mTestView.y = 0;

mTestView.y += 10;

break;

case KeyEvent.KEYCODE_DPAD_UP:

if (mTestView.y <= 0)

mTestView.y = mHeight;

mTestView.y -= 10;

break;

case KeyEvent.KEYCODE_DPAD_LEFT:

if (mTestView.x <= 0)

mTestView.x = mWidth;

mTestView.x -= 10;

break;

case KeyEvent.KEYCODE_DPAD_RIGHT:

if (mTestView.x >= mWidth)

mTestView.x = 0;

mTestView.x += 10;

break;

}

return false;

};

}

2、SurfaceView android.view.SurfaceView

当执行效率有要求很高时,View类就无法满足需求。必须使用SurfaceView 类 -- 利用双缓冲技术

使用SurfaceView提供给需要直接画像素而不是使用画窗体部件的应用使用。

而每个Surface创建一个Canvas对象,用来管理View在Surface上的绘画操作。

简要说明一下具体的方法及使用:

SurfaceHolder 对象需要通过 getHolder() 获取

在 Layout 上摆一个 SurfaceView 组件:

mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);

SurfaceHolder holder = mSurfaceView.getHolder();

对于SurfaceView 的创建,销毁及变更

@SuppressWarnings("unused")

private SurfaceHolder.Callback mSurfaceCbk = new SurfaceHolder.Callback() {

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) { // 在Surface 大小发生变更时触发

// TODO Auto-generated method stub

}

@Override

public void surfaceCreated(SurfaceHolder holder) { // 在创建 Surface 时触发

// TODO Auto-generated method stub

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) { // 在销毁 Surface 时触发

// TODO Auto-generated method stub

}

};

添加及删除 SurfaceView 的回调函数:

display.addCallback(mSurfaceCbk);

display.removeCallback(mSurfaceCbk);

Canvas 的使用:

lockCanvas 锁定画布,绘图之前必须锁定画布才能得到当前画布对象

unlockCanvasAndPost 开始绘制时锁定画布,绘制完成之后解锁画布

下面例子是绘制一个不断变换颜色的圆,并实现 SurfaceView 的事件处理

TestSurfaceView.java 代码:

[java]

package com.example.testondraw;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

/**

* 使用SurfaceView提供给需要直接画像素而不是使用画窗体部件的应用使用。

* 而每个Surface创建一个Canvas对象,用来管理View在Surface上的绘画操作。

*/

public class TestSurfaceView extends SurfaceView implements

SurfaceHolder.Callback {

// 控制循环

private boolean mbLoop = false;

// 定义SurfaceHolder对象

private SurfaceHolder mSurfaceHolder = null;

private int miCount = 0;

public int x = 50, y = 50;

private int mWidth = 1280,mHeight = 720;

private Bitmap mBitmap = null;

public TestSurfaceView(Context context) {

super(context);

// 实例化SurfaceHolder

mSurfaceHolder = this.getHolder();

// 添加回调

mSurfaceHolder.addCallback(this);

this.setFocusable(true);

}

public void setDisplayWH(int w, int h) {

mWidth = w;

mHeight = h;

}

public void setBitmap(Bitmap bitmap) {

this.mBitmap = bitmap;

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

// TODO Auto-generated method stub

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

mbLoop = true;

Thread th = new Thread(new Runnable() {

@Override

public void run() {

while (mbLoop){

try {

Thread.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

synchronized( mSurfaceHolder ){

drawBitmap();

DrawData();

}

}

}

});

th.start();

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

mbLoop = false;

}

private void drawBitmap() {

// 锁定画布,得到canvas

if (mSurfaceHolder == null || this.mBitmap == null)

return;

Canvas canvas = mSurfaceHolder.lockCanvas();

if (canvas == null) {

return;

}

// 绘图

Paint paint = new Paint();

paint.setAntiAlias(true);

paint.setColor(Color.BLUE);

canvas.drawBitmap(this.mBitmap, 0, 0, paint);

// 绘制后解锁,绘制后必须解锁才能显示

mSurfaceHolder.unlockCanvasAndPost(canvas);

}

// 绘图方法

private void DrawData() {

if (mSurfaceHolder == null)

return;

// 锁定画布,得到canvas

Canvas canvas = mSurfaceHolder.lockCanvas();

if (canvas == null) {

return;

}

if (miCount < 100) {

miCount++;

} else {

miCount = 0;

}

// 绘图

Paint mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setColor(Color.BLACK);

// 绘制矩形--清屏作用

canvas.drawRect(0, 0, mWidth, mHeight, mPaint);

switch (miCount % 4) {

case 0:

mPaint.setColor(Color.BLUE);

break;

case 1:

mPaint.setColor(Color.GREEN);

break;

case 2:

mPaint.setColor(Color.RED);

break;

case 3:

mPaint.setColor(Color.YELLOW);

break;

default:

mPaint.setColor(Color.WHITE);

break;

}

// 绘制矩形--

canvas.drawCircle(x, y, 50, mPaint);

// 绘制后解锁,绘制后必须解锁才能显示

mSurfaceHolder.unlockCanvasAndPost(canvas);

}

}

测试使用例子:

[java]

package com.example.testondraw;

import java.util.List;

import android.app.Activity;

import android.app.ActivityManager;

import android.content.Context;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.DisplayMetrics;

import android.util.Log;

import android.view.KeyEvent;

import android.view.Menu;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

public class MainActivity extends Activity {

static final String TAG = "MainActivity";

private TestSurfaceView mTestSurfaceView = null;

private int mWidth = 0, mHeight = 0;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

initView();

startTestSurfaceView();

// setContentView(R.layout.main);

}

void initView() {

// 使用自定义的View

mTestSurfaceView = new TestSurfaceView(this);

setContentView(mTestSurfaceView);

DisplayMetrics dm = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(dm);

mWidth = dm.widthPixels;

mHeight = dm.heightPixels;

Log.i(TAG, "Display Metrics width:" + mWidth + " mHeight:" + mHeight);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {

switch (keyCode) {

case KeyEvent.KEYCODE_DPAD_DOWN:

if (mTestSurfaceView.y >= mHeight)

mTestSurfaceView.y = 0;

mTestSurfaceView.y += 10;

break;

case KeyEvent.KEYCODE_DPAD_UP:

if (mTestSurfaceView.y <= 0)

mTestSurfaceView.y = mHeight;

mTestSurfaceView.y -= 10;

break;

case KeyEvent.KEYCODE_DPAD_LEFT:

if (mTestSurfaceView.x <= 0)

mTestSurfaceView.x = mWidth;

mTestSurfaceView.x -= 10;

break;

case KeyEvent.KEYCODE_DPAD_RIGHT:

if (mTestSurfaceView.x >= mWidth)

mTestSurfaceView.x = 0;

mTestSurfaceView.x += 10;

break;

case KeyEvent.KEYCODE_BACK:

this.finish();

break;

}

return false;

};

void startTestSurfaceView() {

mTestSurfaceView.setDisplayWH(mWidth, mHeight);

}

}

赞助本站

人工智能实验室

相关热词: android开发 教程

相关内容
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港