SurfaceView在创建后永远不可用于绘图。
其他SO问题表明它可以通过传递给它的回调函数进行管理,并且必须在生命周期开始之前将其分配给setContentView。
Logcat表示回调已成功分配,但永远不会被触发。
完整代码here但我认为相关部分可以在主要活动中找到:
package com.example.gavin.pixelarraytest;
import android.app.Activity;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GameView theGame = new GameView(this, 0,0);
SurfaceHolder testt;
testt = theGame.getHolder();
setContentView(theGame);
while(true){
if(testt.getSurface().isValid()){ // this never becomes true. isCreating is also consistently false at this point
theGame.prepareCanvas();
break;
}
}
}
}
在SurfaceView对象中:
package com.example.gavin.pixelarraytest;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
public class GameView extends SurfaceView implements Runnable {
private Paint paint;
private Canvas canvas;
private Bitmap _buffer;
private SurfaceHolder ourHolder;
private boolean running;
private boolean paused = false;
private long fps;
public GameView(Context context, int screenX, int screenY){
ourHolder = getHolder();
ourHolder.addCallback(new MyCallback());
paint = new Paint();
}
public void prepareCanvas(){
running = true;
run();
}
@Override
public void run(){
while(running){
long startFrameTime = System.currentTimeMillis();
draw();
long endFrameTime = System.currentTimeMillis() - startFrameTime;
if(endFrameTime >= 1){
fps = 1000 / endFrameTime;
}
}
private void update(){
class MyCallback implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
private void draw(){
this.setWillNotDraw(false);
if(ourHolder.getSurface().isValid()){
canvas = ourHolder.lockCanvas();
canvas.drawColor(Color.argb(255,100,40,40));
int width = 100;
int height = 100;
int colors[] = new int[width*height];
for (int i = 0; i < colors.length; i++){
int a = 255, r = 40, g = 100, b = 40;
colors[i] = (a << 24) | (r << 16) | (g << 8) | b;
_buffer = Bitmap.createBitmap(colors, width, height, Bitmap.Config.RGB_565);
canvas.drawBitmap(_buffer, 0,0,null);
}
}
}
我是否误解了SurfaceView的使用方式,或者我在上面错误地使用了它?
答案 0 :(得分:1)
要为画布对象充气,您可以试试这个:
首先在res&gt; layout
中创建一个布局文件 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GameView
android:id="+@id/mGameView"
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
</LinearLayout>
然后你可以通过调用
来膨胀它setContentView(R.layout.your_file_name);
最后使用以下方式访问游戏视图:
GameView gameView = findViewById(R.id.mGameView);
gameView.prepareCanvas();