展会信息港展会大全

理解自制SurfaceView代码
来源:互联网   发布日期:2015-10-13 07:40:42   浏览:1172次  

导读:概述: 最近在读himi的android游戏开发专栏,其中通过前几张剖析View的继承接口类发现SurfaceView比较适合做Game Dev然后本人也动手跟着him...

概述:

最近在读himi的android游戏开发专栏,其中通过前几张剖析View的继承接口类发现SurfaceView比较适合做Game Dev然后本人也动手跟着himi的代码敲了几下。最终虽然也达到了himi的运行效果。但是其中还是经过了好多疑点。现在本人将自己的理解发布出来,欢迎交流与学习

Code List:

[java]

import android.content.Context;

import android.content.Intent;

import android.content.res.Resources;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.Log;

import android.view.MotionEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

public class LoginView extends SurfaceView implements Callback,Runnable{

private Canvas canvas; //定义画布对象

private Thread thread; //定义线程线程对应

private int ScreenW,ScreenH; //定义屏幕的宽度和高度

private Paint paint; //定义画笔对象

private SurfaceHolder sh; //声明SurfaceHolder对象

private Resources resources; //声明资源对象

private Bitmap bitmapr; //注册bitmap

private Bitmap bitmapb; //背景bitmap

private int bp_x,bp_y; //注册背景图宽度高?

private boolean flag;

public static String zh_k = "注册页面";

private boolean zh_flag = true;

private String str_pass = "aaa";

//初始构?

public LoginView(Context context) {

super(context);

//

resources = this.getResources();

bitmapr = BitmapFactory.decodeResource(resources, R.drawable.register); //注册窗口

bitmapb = BitmapFactory.decodeResource(resources, R.drawable.duola); //注册背景?

thread = new Thread(this);

sh = this.getHolder();

sh.addCallback(this);

paint = new Paint();

paint.setColor(Color.RED);

paint.setAntiAlias(true); //去掉锯齿

this.setFocusable(true);

this.setKeepScreenOn(true); //设置屏幕常亮

resources = this.getResources();

}

public void draw(){

canvas = sh.lockCanvas(); //得到画布对象

paint.setColor(Color.RED);

if(null != canvas){ //在设置横屏的时候 坐标算法如下

canvas.drawColor(Color.WHITE);

canvas.drawBitmap(bitmapb,

-(bitmapb.getWidth() - ScreenW), -(bitmapb

.getHeight() - ScreenH), paint);

//2、3参数为x坐标和y坐标,就是位图paint的左上角位置

canvas.drawBitmap(bitmapr, bp_x,bp_y, paint);

sh.unlockCanvasAndPost(canvas);

}

}

@Override

public void run() {

while(!flag){

draw();

try {

thread.sleep(1000);

} catch (Exception e) {

Log.v("run", "error");

}

}

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

ScreenW = this.getWidth();

ScreenH = this.getHeight();

bp_x = ScreenW/2-bitmapr.getWidth()/2;

bp_y = ScreenH/2-bitmapr.getHeight()/2;

thread.start();

}

@Override

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

int height) {

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override

public boolean onTouchEvent(MotionEvent event) {

float x = event.getX();

float y = event.getY();

if(x > bp_x+14 && x < bp_x+129){ //锁定登陆框姓名区域X轴

if(y >= bp_y+43 && y <= bp_y+58){ //锁定登陆框姓名区域Y轴

Intent intent = new Intent();

intent.putExtra("name", "zhanglei");

intent.setClass(MainActivity.instance, Register.class);

MainActivity.instance.startActivity(intent);

}

}

return super.onTouchEvent(event);

}

}

import android.content.Context;

import android.content.Intent;

import android.content.res.Resources;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.Log;

import android.view.MotionEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

public class LoginView extends SurfaceView implements Callback,Runnable{

private Canvas canvas; //定义画布对象

private Thread thread; //定义线程线程对应

private int ScreenW,ScreenH; //定义屏幕的宽度和高度

private Paint paint; //定义画笔对象

private SurfaceHolder sh; //声明SurfaceHolder对象

private Resources resources; //声明资源对象

private Bitmap bitmapr; //注册bitmap

private Bitmap bitmapb; //背景bitmap

private int bp_x,bp_y; //注册背景图宽度高?

private boolean flag;

public static String zh_k = "注册页面";

private boolean zh_flag = true;

private String str_pass = "aaa";

//初始构?

public LoginView(Context context) {

super(context);

//

resources = this.getResources();

bitmapr = BitmapFactory.decodeResource(resources, R.drawable.register); //注册窗口

bitmapb = BitmapFactory.decodeResource(resources, R.drawable.duola); //注册背景?

thread = new Thread(this);

sh = this.getHolder();

sh.addCallback(this);

paint = new Paint();

paint.setColor(Color.RED);

paint.setAntiAlias(true); //去掉锯齿

this.setFocusable(true);

this.setKeepScreenOn(true); //设置屏幕常亮

resources = this.getResources();

}

public void draw(){

canvas = sh.lockCanvas(); //得到画布对象

paint.setColor(Color.RED);

if(null != canvas){ //在设置横屏的时候 坐标算法如下

canvas.drawColor(Color.WHITE);

canvas.drawBitmap(bitmapb,

-(bitmapb.getWidth() - ScreenW), -(bitmapb

.getHeight() - ScreenH), paint);

//2、3参数为x坐标和y坐标,就是位图paint的左上角位置

canvas.drawBitmap(bitmapr, bp_x,bp_y, paint);

sh.unlockCanvasAndPost(canvas);

}

}

@Override

public void run() {

while(!flag){

draw();

try {

thread.sleep(1000);

} catch (Exception e) {

Log.v("run", "error");

}

}

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

ScreenW = this.getWidth();

ScreenH = this.getHeight();

bp_x = ScreenW/2-bitmapr.getWidth()/2;

bp_y = ScreenH/2-bitmapr.getHeight()/2;

thread.start();

}

@Override

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

int height) {

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override

public boolean onTouchEvent(MotionEvent event) {

float x = event.getX();

float y = event.getY();

if(x > bp_x+14 && x < bp_x+129){ //锁定登陆框姓名区域X轴

if(y >= bp_y+43 && y <= bp_y+58){ //锁定登陆框姓名区域Y轴

Intent intent = new Intent();

intent.putExtra("name", "zhanglei");

intent.setClass(MainActivity.instance, Register.class);

MainActivity.instance.startActivity(intent);

}

}

return super.onTouchEvent(event);

}

}

运行效果图:

\

方法执行顺序:

LoginView-->surfaceCreated-->run-->draw

方法解析:

LoginView方法:

OK,我们看到LoginView其实是在初始化本View的一些全局变量,包括线程对象、位图对象。另外设置了一些效果,包括去掉锯齿等。程序中注释特别明朗

surfaceCreated方法:

本方法体中我们看到初始化了2组长度和高度。其中Sreen顾名思义我就不再解释。bp_x和bp_y指的是注册图片在屏幕中的开始坐标的位置。也就是左上角的位置[算法解析:“屏幕的一半坐标为中心点坐标-注册图片一半的像素值”]得到的就为绘制图片位图的起始位置。你明白了吗?

run方法:

run方法为thread线程开始的跑的标示,代码逻辑很简单不再解释

draw方法:

OK,本人觉得draw方法才是一个View中最核心的内容。因为它负责在屏幕上绘制内容和刷新内容。本人将himi博客的内容简单化了很多。应该很好理解吧。

拿到canvas到画两个位图其中的注释写的很清楚本人不再多说

注意:

本人在做此案例的时候遇到了1个特别棘手的问题那就是按照himi的源代码自己new的一个项目居然在paint位图的时候遇到了错乱的问题。

说明:

登陆窗口的用户名和密码的点击事件是通过重写onTouchEvent方法来实现的。锁定了相关的像素坐标区域。如果该区域被点击了就发送一个Intent。其中Intent的传参为put的那个方法,另外在AndroidManifest.xml文件中注意声明你Intent跳转的Activity

声明:本人也是一名Android新手,欢迎大家一起交流与学习。稍后本人将发布本博文的源码地址。因为公司网络不好,可能会在晚上回家之后upload上去

赞助本站

人工智能实验室

相关热词: android开发 教程

AiLab云推荐
展开

热门栏目HotCates

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