java - 无法使用自定义视图在画布上绘图
问题描述
我有一个课程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
对象传递给一切都很好,并且 draw() 方法工作正常,这意味着是有效的。mGameView
GameView
setContentView
mSurfaceHolder.getSurface().isValid())
但是,如果我上第一堂课,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);
一切都很好,只是我只有一个视图不能覆盖按钮等等,这不是我想要的。
我究竟做错了什么?我试图尽可能好地遵循该链接。我正在尝试几天来解决这个问题,但也无法在任何地方找到解决方案。
解决方案
代替
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 是您布局中的一个。
推荐阅读
- python - 创建两个字典并从文本文件中分配键和值
- c++ - 头文件中的 constexpr const char*
- azure-cosmosdb - CosmosDB 的 Python SDK 是否不允许进行令牌/凭据身份验证?
- reactjs - 如何从其他组件触发组件更改?
- excel - 连接彼此偏移的幂查询列
- android - Flutter:在 /usr/lib/android-sdk/platforms 中找不到有效的 Android SDK 平台。目录为空
- maven-surefire-plugin - 报告 @TestFactory 的测试用例名称
- azure - Azure devops VSTS 现在没有在我的主机上安装 awscli,以前可以工作
- python - 按顺序合并数据框列表
- .net - 模型存储 edmx 文件不会在调试模式下生成,但会在发布模式下生成