无法在具有自定义视图的画布上绘制

时间:2018-08-06 19:59:16

标签: java android android-studio android-custom-view surfaceview

我有一个GameActivity类,如下所示(我只发布了相关部分):

public class GameActivity extends AppCompatActivity {

// initiate variables
private GameView mGameView;
private Display mDisplay;
private Point mSize;

public static int window_width = 0;
public static int window_height = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    mDisplay = getWindowManager().getDefaultDisplay();
    mSize = new Point();
    mDisplay.getSize(mSize);
    window_width = mSize.x;
    window_height = mSize.y;

    // initialize game view object
    mGameView = new GameView(this);

    // adding it to the content view
    //setContentView(mGameView);
    setContentView(R.layout.activity_game);
}

由于自定义视图,我具有两个构造函数的类GameView如下:

private Context mContext;

//These objects will be used for drawing
private SurfaceHolder mSurfaceHolder;
private Paint mPaint;

public GameView(Context context){
    super(context);

    Log.d("TEST","Constructor 1");

    init(context, null);

    // clear all lists
    ...

    // create object of map in beginning of game
    ...

    // create objects of HQs
    ...

   // create other sprite objects and add them to lists
   ...
}

public GameView(Context context, AttributeSet attrs) {
    super(context, attrs);

    Log.d("TEST","Constructor 2");

    init(context, attrs);

}

然后我在两个构造函数中调用init()方法

private void init(Context context, AttributeSet attrs) {
    mContext = context;
    mSurfaceHolder = getHolder();
    mPaint = new Paint();
    mPaint.setColor(Color.DKGRAY);
}

我的run()是这样的:

@Override
public void run(){


    Log.d("TEST","RUN");
    long current_time = 0;
    long old_time;


    while (playing) {
        old_time = current_time;


        // update the game
        update();

        //to draw the frame
        //onDraw(canvas);
        draw();

        //to control (lets the game sleep for some milliseconds)
        control();

        current_time = SystemClock.elapsedRealtime();

        frametime = current_time - old_time;
        framerate = 1000/ (current_time - old_time);

    }
}

draw()(发生错误的地方)是这样的:

private void draw() {
    // BUG: mSurfaceHolder.getSurface.isValid ist niemals valid

    Canvas canvas;

    //if(true){
    //checking if surface is valid
    if (mSurfaceHolder.getSurface().isValid()) {
        Log.d("Test","DRAW");

        //locking the canvas
        canvas = mSurfaceHolder.lockCanvas();

        //drawing a background color for canvas
        canvas.drawColor(Color.GREEN);

        // call draw methods here
        // bigger objects should be called before smaller objects for visibility
        draw_ground(canvas);
        draw_hq(canvas);
        draw_soldiers(canvas);
        draw_bullets(canvas);
        draw_HUD(canvas);

        //Unlocking the canvas
        mSurfaceHolder.unlockCanvasAndPost(canvas);
    }
}

没有问题是: 如果我在第一个类GameActivity中将类mGameView的对象GameView传递给setContentView,一切都很好,并且draw()方法正常工作,这意味着{{1} }有效。

但是,如果我输入第一堂课mSurfaceHolder.getSurface().isValid()),那么setContentView(R.layout.activity_game);就永远无效。其他一切正常(例如,我听到游戏声音),但他没有画画。如果我没有检查mSurfaceHolder.getSurface().isValid()),那么游戏会崩溃,因为在mSurfaceHolder.getSurface().isValid())下面的代码中,draw()是空的。

我的目的是创建一个自定义视图,并在其上覆盖按钮。

这是XML:

canvas

该XML似乎是正确的,因为Android Studio可以识别它(带有叠加按钮的自定义视图)。但是他没有参加。 enter image description here

就像我对<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".GameActivity"> <!--Test--> <com.example.mirco.battlefront.GameView android:id="@+id/gameView" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:id="@+id/button" android:layout_width="119dp" android:layout_height="wrap_content" android:text="Button" /> <!--Test--> </FrameLayout> 所说的那样,一切都很好,除了我只有一个视图无法覆盖按钮等,而这并不是我想要的。

我在做什么错?我尝试尽可能地遵循该LINK。我现在尝试了几天来解决这个问题,但是也找不到任何解决方案。 希望有人可以提供帮助?如果信息丢失,我将更新问题。如果您不赞成,请评论原因,以便我学习。谢谢!

1 个答案:

答案 0 :(得分:0)

代替

mGameView = new GameView(this);

    // adding it to the content view
    //setContentView(mGameView);
    setContentView(R.layout.activity_game);

您应该

setContentView(R.layout.activity_game);
mGameView = (GameView)findViewById (R.id.gameView);

然后mGameview是您布局中的一个。