2013-06-13 5 views
0

Может ли кто-нибудь помочь, мое приложение, похоже, не делает onDraw() в классе GraView, даже если .invalidate вызывается изнутри или вне класса. Мне удалось выяснить с помощью system.err, что он делает недействительным представление, однако он никогда не попадает в onDraw(), хотя остальная часть приложения продолжает работать. Я обнаружил много решений, связанных с установкой setWillNotDraw (false) в конструкторе, но это ничего не решило.onDraw (Холст холст) никогда не достигал?

GravIO.java Файл:

package dabawi.gravitas; 

import android.app.Activity; 
import android.content.Context; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.os.Bundle; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 

public class GravIO extends Activity implements Runnable, OnTouchListener { 
public final static int clock = 1000; 
private GravEngine engine; 
private GraView TV; 
private SensorManager mSensorManager; 
private Sensor mSensor; 
private Thread t1; 


public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    t1 = new Thread(this); 
    t1.start(); 
    engine = new GravEngine(); 
    TV = new GraView(this, engine); 
    setContentView(TV); 
    TV.setOnTouchListener(this); 
    TV.setVisibility(View.VISIBLE);  
    //mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
    System.err.println("Starting Engine") ; 

    run(); 
} 

@Override 
public void run() { 
    while (true) { 
     try { 
      System.err.println("Tik") ; 
      engine.tick(); 
      TV.invalidate(); 
      Thread.sleep(GravIO.clock); 
     } catch (InterruptedException ex) { 
      System.err.println("faal"); 
     } 
    } 
} 

@Override 
public boolean onTouch(View view, MotionEvent event) { 
    engine.switchGravity(); 
    return true; 
} 

} 

GraView.java Файл:

package dabawi.gravitas; 

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.view.Display; 
import android.view.View; 
import android.view.WindowManager; 

@SuppressLint({ "DrawAllocation", "ViewConstructor" }) 
public class GraView extends View { 
private GravEngine engine; 
private int screenWidth, screenHeight, ySpace = 5, xSpace, scale; 
private Paint paint; 
private int xLoc, yLoc; 
private boolean xWall = false, yWall = false; 

public GraView(Context context, GravEngine engine) { 
    super(context); 
    setWillNotDraw(false); 
    this.engine = engine; 
    calcScale(context); 
} 

@Override // We think the problem is with this method, that it is never called upon. 
public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    System.err.println("Calculating position"); 
    calcPos(); 
    canvas = new Canvas(); 
    // drawing background 
    paint = new Paint(); 
    paint.setStyle(Paint.Style.FILL); 
    paint.setColor(Color.WHITE); 
    canvas.drawPaint(paint); 

    drawGame(canvas); 
} 

private void drawGame(Canvas canvas) { 
    drawRoom(canvas); 
    drawPlayer(canvas); 
} 


@SuppressWarnings("deprecation") 
private void calcScale(Context context) { 
    WindowManager wm = (WindowManager) context 
      .getSystemService(Context.WINDOW_SERVICE); 
    Display d = wm.getDefaultDisplay(); 

    screenWidth = d.getWidth(); 
    screenHeight = d.getHeight(); 
    scale = screenHeight/ySpace; 
    xSpace = screenWidth/scale; 
} 

private void calcPos() { 
    xLoc = (engine.getxPlayer()/GravEngine.roomScaling); 
    yLoc = (engine.getyPlayer()/GravEngine.roomScaling); 
    if (xLoc < (xSpace + 1)/2) { 
     xLoc = (xSpace + 1)/2; 
     xWall = true; 
    } else if (xLoc > (GravRoom.xSize - ((xSpace + 1)/2))) { 
     xLoc = GravRoom.xSize - ((xSpace + 1)/2); 
     xWall = true; 
    } else { 
     xWall = false; 
    } 
    if (yLoc < (ySpace + 1)/2) { 
     yLoc = (ySpace + 1)/2; 
     yWall = true; 
    } else if (yLoc > (GravRoom.xSize - ((ySpace + 1)/2))) { 
     xLoc = GravRoom.ySize - ((ySpace + 1)/2); 
     yWall = true; 
    } else { 
     yWall = false; 
    } 
} 

private void drawPlayer(Canvas canvas) { 
    float xPos = engine.getxPlayer()/GravEngine.roomScaling, yPos = engine 
      .getyPlayer()/GravEngine.roomScaling; 
    if (xWall) { 

    } 
    if (yWall) { 

    } 
    paint.setColor(Color.BLUE); 
    int left = (int) (xPos * scale), top = (int) (yPos * scale); 
    int right = left + (GravEngine.pxSize/GravEngine.roomScaling) * scale; 
    int bot = top + (GravEngine.pySize/GravEngine.roomScaling) * scale; 
    canvas.drawRect(left, top, right, bot, paint); 
} 

private void drawRoom(Canvas canvas) { 
    for (int i = 0, x = xLoc - ((xSpace + 1)/2); i < xSpace + 1; x++, i++) { 
     for (int j = 0, y = yLoc - ((ySpace + 1)/2); i < ySpace + 1; y++, j++) { 
      drawRoomPart(x,y,i,j,canvas); 
     } 
    } 
} 

private void drawRoomPart(int x, int y, int i, int j, Canvas canvas) { 
    if (x >= 0 && y >= 0 && x < GravRoom.xSize && y < GravRoom.ySize) { 
     short type = engine.getRoom(engine.getCurrentRoom()).getGridPos(x,y); 
     if (type != 0) { 
      drawBlock(canvas, i, x, j, y, type); 
     } 
    } 
} 

private void drawBlock(Canvas canvas, int i, int x, int j, int y, short type) { 
    int left = i * scale, top = y * scale; 
    int right = left + scale; 
    int bot = top + scale; 
    paint.setColor(colorBlock(type)); 
    canvas.drawRect(left, top, right, bot, paint); 
    System.err.println("Left" + left + " top: " + top + " right: " 
      + right + " bot: " + bot); 
} 

private int colorBlock(short type) { 
    if (type == 1) { 
     return Color.DKGRAY; 
    } else if (type == 2) { 
     return Color.CYAN; 
    } else if (type == 3) { 
     return Color.GREEN; 
    } else if (type == 4) { 
     return Color.RED; 
    } else { 
     return Color.MAGENTA; 
    } 
} 

// private void imageBlock(short type) { 
// 
// } 

} 

ответ

0

Ой!

Ваш вызов метода запуска выполняется в UIThread (как метод onCreate), и он выполняет бесконечный цикл в нем. Просто добавьте println после вызова, и вы увидите, что поток пользовательского интерфейса никогда не выпускается, ваше приложение даже не должно запускаться!

+0

Благодарим за отзыв, это объясняет многое. Из того, что я понимаю, это должно помочь, если запуск будет выполнен в другом потоке (исправьте меня, если я ошибаюсь), но если да, то как сделать эту разрез легко на андроиде? – Dave

+0

Более быстрый способ - заменить «run()» на «new Thread (this) .start();» – Zoubiock

+0

Но вы должны увидеть эту вещь по-другому: сначала реализуйте метод onMesure вашего представления, а там ширина и высота retreive, это будет более точно, чем defaultDesplay. Затем, получите поток в представлении, в нем рассчитывается позиция ваших предметов, и когда это будет сделано, вызовите метод invalidate. Таким образом, вычисление будет не на нити ui. Также не создавайте объект, например Paint, в методе рисования. Кроме того, почему вы создаете новый холст? – Zoubiock

0

Вы не видите никаких изменений, так как вы создаете новый холст и нарисовываете его. Чтобы это исправить, удалить строку

canvas = new Canvas(); 

Кроме того, вы должны начать свой Paint вне метода onDraw (это оптимизация рекомендуется в документации Android).

Смежные вопросы