无法使用自定义视图在 canvas 上绘图
Cannot draw on canvas with custom view
我有一个classGameActivity
如下(我只是post相关部分):
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);
}
由于自定义视图,我有如下两个构造函数的 class 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);
}
}
不,问题是:
如果我在第一个 class GameActivity
中将 class GameView
的对象 mGameView
传递给 setContentView
一切都很好并且 draw() 方法工作正常,这意味着 mSurfaceHolder.getSurface().isValid())
有效。
但是如果我输入第一个 class setContentView(R.layout.activity_game);
那么 mSurfaceHolder.getSurface().isValid())
永远无效。其他一切正常(例如,我听到游戏声音)但他不画画。如果我不检查 mSurfaceHolder.getSurface().isValid())
那么游戏就会崩溃,因为在下面的代码中 draw()
canvas
是空的。
我的目标是创建自定义视图并用按钮覆盖它。
这里是 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>
XML 似乎是正确的,因为 Android Studio 可以识别它(带有叠加按钮的自定义视图)。但他没有画进去。
就像我在 setContentView(mGameView);
中所说的那样,一切都很好,除了我只有一个视图,我无法在其中覆盖按钮等等,这不是我想要的。
我做错了什么?我试图尽可能地遵循 LINK。我已经尝试了几天来解决这个问题,但也找不到解决方案。
而不是
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 就是您布局中的那个。
我有一个classGameActivity
如下(我只是post相关部分):
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);
}
由于自定义视图,我有如下两个构造函数的 class 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);
}
}
不,问题是:
如果我在第一个 class GameActivity
中将 class GameView
的对象 mGameView
传递给 setContentView
一切都很好并且 draw() 方法工作正常,这意味着 mSurfaceHolder.getSurface().isValid())
有效。
但是如果我输入第一个 class setContentView(R.layout.activity_game);
那么 mSurfaceHolder.getSurface().isValid())
永远无效。其他一切正常(例如,我听到游戏声音)但他不画画。如果我不检查 mSurfaceHolder.getSurface().isValid())
那么游戏就会崩溃,因为在下面的代码中 draw()
canvas
是空的。
我的目标是创建自定义视图并用按钮覆盖它。
这里是 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>
XML 似乎是正确的,因为 Android Studio 可以识别它(带有叠加按钮的自定义视图)。但他没有画进去。
就像我在 setContentView(mGameView);
中所说的那样,一切都很好,除了我只有一个视图,我无法在其中覆盖按钮等等,这不是我想要的。
我做错了什么?我试图尽可能地遵循 LINK。我已经尝试了几天来解决这个问题,但也找不到解决方案。
而不是
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 就是您布局中的那个。