我有一个简单的应用程序,它通过嵌套在活动布局中的SurfaceView在屏幕上显示图像。
我有一个SurfaceViewExample类,它创建一个OurView的新实例,并包含按钮调用的方法。有三种方法:
moveImage(int xChange,int yChange),在该方向上移动图像所需的x和y更改。
public void arrowPressed(View view) {
switch (view.getId()) {
case R.id.arrowLeft:
arrowAction(gameView, "left");
break;
case R.id.arrowRight:
arrowAction(gameView, "right");
break;
case R.id.arrowUp:
arrowAction(gameView, "up");
break;
}
}
------------------------------------------------------------------------------------
void arrowAction(OurView ourView, String direction) {
switch (direction) {
case "left":
ourView.moveImage(-1,0);
break;
case "right":
ourView.moveImage(1,0);
break;
case "up":
ourView.moveImage(0,1);
break;
}
}
------------------------------------------------------------------------------------
void moveImage(int xChange, int yChange) {
xCoord = xCoord + xChange;
yCoord = yCoord + yChange;
}
这一切似乎都按预期工作。 moveImage被成功调用,它修改了xCoord和yCoord变量。当我从moveImage中打印x和y Coords时,它们会反映其更改的值。但是,在moveImage中xCoord和yCoord以及线程MyThread中的xCoord和yCoord之间似乎存在脱节。
方法doDraw(Canvas canvas)在(xPos,yPos)处绘制位图(这些变量只是调整了x和y Coords,以便图像以该坐标点为中心,而不是让它的左上角位于该坐标点上坐标点)。当我从这种方法打印x和y Coords时,它们会反映原始值。
public void doDraw(Canvas canvas) {
xPos = xCoord - (testimg.getWidth()/2);
yPos = yCoord - (testimg.getHeight()/2);
canvas.drawBitmap(testimg, xPos, yPos, null);
}
我能想到这一点的唯一原因是moveImage正在创建名为xCoord和yCoord的新局部变量。但是这没有意义,因为它成功获得了xCoord和yCoord的原始值。
完整代码:
SurfaceViewExample:
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.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
public class SurfaceViewExample extends Activity {
OurView gameView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameView = new OurView(this);
setContentView(R.layout.activity_surface_view_example);
}
public void arrowPressed(View view) {
switch (view.getId()) {
case R.id.arrowLeft:
arrowAction(gameView, "left");
break;
case R.id.arrowRight:
arrowAction(gameView, "right");
break;
case R.id.arrowUp:
arrowAction(gameView, "up");
break;
}
}
void arrowAction(OurView ourView, String direction) {
switch (direction) {
case "left":
ourView.moveImage(-1,0);
break;
case "right":
ourView.moveImage(1,0);
break;
case "up":
ourView.moveImage(0,1);
break;
}
}
}
OurView:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
public class OurView extends SurfaceView implements SurfaceHolder.Callback {
private MyThread myThread;
private SurfaceHolder holder;
private Bitmap testimg;
public int xCoord = 500;
public int yCoord = 500;
int xPos;
int yPos;
public OurView(Context context) {
super(context);
init();
}
public OurView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public OurView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
myThread = new MyThread(this);
holder = getHolder();
holder.addCallback(this);
testimg = BitmapFactory.decodeResource(getResources(),R.drawable.testimg);
}
void moveImage(int xChange, int yChange) {
xCoord = xCoord + xChange;
yCoord = yCoord + yChange;
System.out.println("-----");
System.out.println("-----");
System.out.println(xCoord);
System.out.println(yCoord);
System.out.println("-----");
System.out.println("-----");
}
public void doDraw(Canvas canvas) {
System.out.println("Starting drawing...");
System.out.println(xCoord);
System.out.println(yCoord);
xPos = xCoord - (testimg.getWidth()/2);
yPos = yCoord - (testimg.getHeight()/2);
System.out.println(xPos);
System.out.println(yPos);
canvas.drawBitmap(testimg, xPos, yPos, null);
System.out.println("Drawing finished.");
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
myThread.setRunning(true);
myThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
myThread.setRunning(false);
while (retry) {
try {
myThread.join();
retry = false;
}
catch (InterruptedException e) {}
}
}
}
MyThread的:
import android.graphics.Canvas;
public class MyThread extends Thread{
OurView myView;
private boolean running = false;
public MyThread(OurView view) {
myView = view;
}
public void setRunning(boolean run) {
running = run;
}
@Override
public void run() {
while(running){
Canvas canvas = myView.getHolder().lockCanvas();
if(canvas != null){
synchronized (myView.getHolder()) {
myView.doDraw(canvas);
}
myView.getHolder().unlockCanvasAndPost(canvas);
}
try {
sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
MyThread类几乎是来自Create animation on SurfaceView in background Thread的纯副本+粘贴。
答案 0 :(得分:0)
每次调用onDraw时,都会更改Canvas对象表单MyThread。您不应该在其他类中引用Canvas。