简体   繁体   English

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

[英]Cannot draw on canvas with custom view

I have a class GameActivity as follows (I just post the relevant part): 我有一个如下类的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);
}

And I have the class GameView as follows with two constructors because of the custom view (also just the relevant parts to keep it clear): 而且由于自定义视图,我还具有两个构造函数的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);

}

And I call in both of the constructors the init() method 我将两个构造函数都调用init()方法

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

My run() is like this: 我的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);

    }
}

And the draw() (where the mistake happens) is like this: 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);
    }
}

No the question is: If I in the first class GameActivity pass the object mGameView of the class GameView to setContentView everything is fine and the draw() methods works normal which means mSurfaceHolder.getSurface().isValid()) is valid. 没有的问题是:如果我在第一类GameActivity传递对象mGameView类的GameViewsetContentView一切都很好,平局()方法,工作正常,这意味着mSurfaceHolder.getSurface().isValid())是有效的。

But if I put in the first class setContentView(R.layout.activity_game); 但是,如果我将第一类设置为setContentView(R.layout.activity_game); then mSurfaceHolder.getSurface().isValid()) is never valid. 那么mSurfaceHolder.getSurface().isValid())永远无效。 Everything else works (eg I hear the game sound) but he doesn't draw. 其他一切都起作用(例如,我听到游戏声音),但他没有画画。 If I don't check for mSurfaceHolder.getSurface().isValid()) then the game crashes because in the code below in draw() the canvas is empty. 如果我不检查mSurfaceHolder.getSurface().isValid())则游戏会崩溃,因为在draw()下面的代码中, canvas是空的。

My aim is to create a custom view and overlay this with buttons. 我的目的是创建一个自定义视图,并在其上覆盖按钮。

Here is the XML: 这是XML:

<?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>

The XML seems to be correct because Android Studio recognizes it (custom view with overlayed button). XML似乎是正确的,因为Android Studio可以识别它(带有叠加按钮的自定义视图)。 But he doesn't draw in it. 但是他没有参加。 在此处输入图片说明

Like I said with setContentView(mGameView); 就像我说的setContentView(mGameView); everything is fine except that I only have one view where I can't overlay buttons and so on which is not what I want. 一切都很好,除了我只有一个视图无法覆盖按钮等等,而这并不是我想要的。

What am I doing wrong? 我究竟做错了什么? I tried to follow that LINK as good as possible. 我尝试尽可能地遵循该链接 I am trying for days now to solve this but also can't find the solution anywhere. 我现在尝试了几天来解决这个问题,但是也找不到任何解决方案。

Instead of 代替

mGameView = new GameView(this);

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

You should do 你应该做

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

Then the mGameview is the one in your layout. 那么mGameview是您布局中的一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM