Android应用程序上未显示自定义可绘制视图
我目前正在构建一个Android应用程序,它根据难度设置生成一个迷宫,轻松生成一个5x5的迷宫,有边框,中等8x8,硬11x11。迷宫由黑色方块组成,这些方块的位置构成了一条从左上到右下的路径,以及迷宫周围的一个正方形边界。如果有一个黑色的正方形,你不能朝那个方向移动,等等。。。目前,只有界面正在构建中,没有任何用户交互,我将在稍后添加。代码也有点混乱-我知道这一点,并将在问题解决后进行整理 问题是迷宫没有显示——只是一个空白!我使用一个XML文件和活动作为主界面,并使用一个自定义视图作为迷宫的可绘制视图 这是在游戏中创建界面的活动/类。这里使用的Level类保存有关当前分数/迷宫/用户位置等的数据。它已经过测试,我非常相信它能工作Android应用程序上未显示自定义可绘制视图,android,Android,我目前正在构建一个Android应用程序,它根据难度设置生成一个迷宫,轻松生成一个5x5的迷宫,有边框,中等8x8,硬11x11。迷宫由黑色方块组成,这些方块的位置构成了一条从左上到右下的路径,以及迷宫周围的一个正方形边界。如果有一个黑色的正方形,你不能朝那个方向移动,等等。。。目前,只有界面正在构建中,没有任何用户交互,我将在稍后添加。代码也有点混乱-我知道这一点,并将在问题解决后进行整理 问题是迷宫没有显示——只是一个空白!我使用一个XML文件和活动作为主界面,并使用一个自定义视图作为迷宫的
public class InGameInterface extends Activity {
Level level;;
MazeView maze;
private boolean[][] currentMaze = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.in_game_interface);
level = new Level();
currentMaze = level.getNewMaze();
loadMazeDisplay();
}
private void loadMazeDisplay()
{
maze = new MazeView(this, level, currentMaze);
RelativeLayout mazeHolder = (RelativeLayout) findViewById(R.id.maze);
LayoutParams lP = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mazeHolder.addView(maze, lP);
}
}
下面是我试图插入自定义视图的XML文件的相关部分。我想说的是,忘记宽度像素和高度像素,因为它们取决于布局。要使用它们,您必须按照可能需要的度量来实现。但是,由于视图非常简单,只需使用canvas.getWidth和getHeight中的值即可。试试下面的方法,看看是否有效
private static final int CELLS_PER_SCREEN = 5; // the number of cells that fit on a view
protected void onDraw(Canvas canvas) {
int totalWidth=canvas.getWidth(),
totalHeight=canvas.getHeight(),
cellWidthInPixels=totalWidth / CELLS_PER_SCREEN,
cellHeightInPixels=totalHeight / CELLS_PER_SCREEN;
canvas.drawRect(0, 0, totalWidth, totalHeight, background);
for (int counterX = 0, xlen=level.getWidth(); counterX < xlen; counterX++) {
for (int counterY = 0, ylen=level.getHeight(); counterY < ylen; counterY++) {
if (!mazeIsPath[counterX][counterY]) {
canvas.drawRect(
(float)(cellWidthInPixels * counterX),
(float)(cellHeightInPixels * counterX),
(float)(cellWidthInPixels * (counterX + 1)),
(float)(cellHeightInPixels * (counterY + 1)), cell
);
}
}
}
canvas.drawCircle( (float)((cellWidthInPixels * level.getCurrentX()) + (0.5f*(cellWidthInPixels))), (float)((cellHeightInPixels * level.getCurrentX()) + (0.5f*(cellHeightInPixels))), (float)(cellHeightInPixels * (2f/3f)), ball);
canvas.drawCircle( (float)((cellWidthInPixels * level.getFinalX()) + (0.5f*(cellWidthInPixels))), (float)((cellHeightInPixels * level.getFinalX()) + (0.5f*(cellHeightInPixels))), (float)(cellHeightInPixels * (4f/5f)), target);
Log.w("onDraw width", widthInPixels.toString());
Log.w("onDraw height", heightInPixels.toString());
Integer cWidth = new Integer(canvas.getWidth());
Integer cHeight = new Integer(canvas.getHeight());
Log.w("canvas width", cWidth.toString());
Log.w("cavas height", cHeight.toString());
}
还有一些关于onDraw的建议:onDraw调用非常频繁,尽可能优化非常重要
使用int而不是Integer,Integer是一个对象,而int只是一个快速的基本类型。
预先计算易于重用的内容,特别是浮点乘法。你的画圈做了很多数学运算,只会随着cellWidthInPixels的变化而变化。。。所以,只要计算一次,每次cellWidthInPixels改变
只是一个简单的猜测。。。在onDraw vs canvas.getWidth和canvas.getHeight中打印heightinpixels、widthinpixels的值。。而且你说的这个白色,是第一个drawrect的背景吗?而且你在哪里初始化cellwidthinpixels?谢谢你的回复-我试着把背景改成灰色,但还是没有显示出来!此外,widthInpixels和heightInPixels均为0,画布宽度为739,画布高度为670。我如上所述修改了onDraw方法上的代码,但没有任何效果-仍然没有显示任何内容!我得说你是个传奇人物D非常感谢你,它现在起作用了——我花了两天时间才弄明白。。。
public class MazeView extends View
{
private Activity context;
private Level level;
private boolean mazeIsPath[][] = null;
private Integer widthInPixels = 0, heightInPixels = 0;
private Integer cellWidthInPixels = 0, cellHeightInPixels = 0;
private Paint cell, ball, background, target;
public MazeView(Context context, Level level, boolean[][] maze)
{
super(context);
this.context = (Activity) context;
this.level = level;
mazeIsPath = maze;
cell = new Paint();
cell.setColor(getResources().getColor(R.color.textColor));
ball = new Paint();
ball.setColor(getResources().getColor(R.color.splashBackground));
background = new Paint();
background.setColor(getResources().getColor(R.color.gameInterfaceBackground));
target = new Paint();
target.setColor(getResources().getColor(R.color.buttonBackground));
widthInPixels = this.getWidth();
heightInPixels = this.getHeight();
setFocusable(true);
this.setFocusableInTouchMode(true);
}
protected void onSizeChanged(Integer newW, Integer newH, Integer oldW, Integer oldH)
{
widthInPixels = newW;
heightInPixels = newH;
super.onSizeChanged(newW, newH, oldW, oldH);
}
protected void onDraw(Canvas canvas)
{
Integer counterX = 0, counterY = 0;
canvas.drawRect(0, 0, widthInPixels, heightInPixels, background);
for(counterX = 0; counterX < level.getWidth(); counterX++)
{
for(counterY = 0; counterY < level.getHeight(); counterY++)
{
if(mazeIsPath[counterX][counterY] != true)
{
canvas.drawRect((float)(cellWidthInPixels * counterX), (float)(cellHeightInPixels * counterX), (float)(cellWidthInPixels * (counterX + 1)), (float)(cellHeightInPixels * (counterY + 1)), cell);
}
}
}
canvas.drawCircle( (float)((cellWidthInPixels * level.getCurrentX()) + (0.5f*(cellWidthInPixels))), (float)((cellHeightInPixels * level.getCurrentX()) + (0.5f*(cellHeightInPixels))), (float)(cellHeightInPixels * (2f/3f)), ball);
canvas.drawCircle( (float)((cellWidthInPixels * level.getFinalX()) + (0.5f*(cellWidthInPixels))), (float)((cellHeightInPixels * level.getFinalX()) + (0.5f*(cellHeightInPixels))), (float)(cellHeightInPixels * (4f/5f)), target);
}
}
protected void onDraw(Canvas canvas)
{
Integer counterX = 0, counterY = 0;
widthInPixels = new Integer(canvas.getWidth());
heightInPixels = new Integer(canvas.getHeight());
canvas.drawRect(0, 0, widthInPixels, heightInPixels, background);
for(counterX = 0; counterX < level.getWidth(); counterX++)
{
for(counterY = 0; counterY < level.getHeight(); counterY++)
{
if(mazeIsPath[counterX][counterY] != true)
{
canvas.drawRect((float)(cellWidthInPixels * counterX), (float)(cellHeightInPixels * counterX), (float)(cellWidthInPixels * (counterX + 1)), (float)(cellHeightInPixels * (counterY + 1)), cell);
}
}
}
canvas.drawCircle( (float)((cellWidthInPixels * level.getCurrentX()) + (0.5f*(cellWidthInPixels))), (float)((cellHeightInPixels * level.getCurrentX()) + (0.5f*(cellHeightInPixels))), (float)(cellHeightInPixels * (2f/3f)), ball);
canvas.drawCircle( (float)((cellWidthInPixels * level.getFinalX()) + (0.5f*(cellWidthInPixels))), (float)((cellHeightInPixels * level.getFinalX()) + (0.5f*(cellHeightInPixels))), (float)(cellHeightInPixels * (4f/5f)), target);
Log.w("onDraw width", widthInPixels.toString());
Log.w("onDraw height", heightInPixels.toString());
Integer cWidth = new Integer(canvas.getWidth());
Integer cHeight = new Integer(canvas.getHeight());
Log.w("canvas width", cWidth.toString());
Log.w("cavas height", cHeight.toString());
}
private static final int CELLS_PER_SCREEN = 5; // the number of cells that fit on a view
protected void onDraw(Canvas canvas) {
int totalWidth=canvas.getWidth(),
totalHeight=canvas.getHeight(),
cellWidthInPixels=totalWidth / CELLS_PER_SCREEN,
cellHeightInPixels=totalHeight / CELLS_PER_SCREEN;
canvas.drawRect(0, 0, totalWidth, totalHeight, background);
for (int counterX = 0, xlen=level.getWidth(); counterX < xlen; counterX++) {
for (int counterY = 0, ylen=level.getHeight(); counterY < ylen; counterY++) {
if (!mazeIsPath[counterX][counterY]) {
canvas.drawRect(
(float)(cellWidthInPixels * counterX),
(float)(cellHeightInPixels * counterX),
(float)(cellWidthInPixels * (counterX + 1)),
(float)(cellHeightInPixels * (counterY + 1)), cell
);
}
}
}
canvas.drawCircle( (float)((cellWidthInPixels * level.getCurrentX()) + (0.5f*(cellWidthInPixels))), (float)((cellHeightInPixels * level.getCurrentX()) + (0.5f*(cellHeightInPixels))), (float)(cellHeightInPixels * (2f/3f)), ball);
canvas.drawCircle( (float)((cellWidthInPixels * level.getFinalX()) + (0.5f*(cellWidthInPixels))), (float)((cellHeightInPixels * level.getFinalX()) + (0.5f*(cellHeightInPixels))), (float)(cellHeightInPixels * (4f/5f)), target);
Log.w("onDraw width", widthInPixels.toString());
Log.w("onDraw height", heightInPixels.toString());
Integer cWidth = new Integer(canvas.getWidth());
Integer cHeight = new Integer(canvas.getHeight());
Log.w("canvas width", cWidth.toString());
Log.w("cavas height", cHeight.toString());
}