0

我在一个布局中有 2 个几乎相同的文本视图,它们由 2 个相似的代码位更新。当应用程序运行时(无论是模拟器还是手机),一个被更新但另一个没有 - 但是当在调试模式下以相同的方式运行时,它们都会被更新。textview我在网上做了很多搜索,阅读了很多问题和答案,并尝试了各种texview更新 . 甚至一条日志消息(与本次更新放在同一个 if 子句中textview)在调试中也有效,但在模拟器上运行时则无效(其他日志消息显示正常)。

该布局还有一个用于简单游戏的画布,相关代码在该游戏的运行中。画布由重复的可运行文件更新。我想为游戏添加一个时间限制,所以我想我只需标记开始时间,然后检查自开始以来的可运行时间。文本视图旨在显示经过的秒数 - 它可以在调试中使用!以下代码的缩写版本。

也许是时间问题,没有时间正常运行?它不需要另一个可运行文件,是吗,因为它正在设法更新另一个 textview 好吗?你应该在runnables中做runnables吗?任何帮助或指导表示赞赏。

布局

<LinearLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/trees2"
android:orientation="vertical"
tools:context=".GameActivity" >
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center"
    android:orientation="horizontal" >
    <TextView
        android:id="@+id/score"
        android:layout_width="54dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_vertical|center_horizontal"
        android:text="0"
        android:background="@drawable/border"
        android:textAppearance="?android:attr/textAppearanceLarge" >
    </TextView>
    <TextView
        android:id="@+id/countdown"
        android:layout_width="54dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_vertical|center_horizontal"
        android:text="0"
        android:background="@drawable/border"
        android:textAppearance="?android:attr/textAppearanceLarge" >
    </TextView>
</LinearLayout>
<TextView
    android:id="@+id/the_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="" />
<couk.jit.drawing.GameBoard
    android:id="@+id/the_canvas"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_margin="20dip" />
</LinearLayout>

游戏板.java

public class GameBoard extends View {
public GameBoard(Context context, AttributeSet aSet) {
    super(context, aSet);
    p = new Paint();
    sprite1 = new Point(-1,-1);
    m = new Matrix();
    bm1 = BitmapFactory.decodeResource(getResources(), R.drawable.b1);
    sprite1Bounds = new Rect(0,0, bm1.getWidth(), bm1.getHeight());
    bm = BitmapFactory.decodeResource(getResources(),R.drawable.go_sign);
}
synchronized public boolean didItHitTarget() {
if .... return true;
else ... return false;
}
@Override
synchronized public void onDraw(Canvas canvas) {
      canvas.drawRect(0, 0, getWidth(), getHeight(), p);
      canvas.drawBitmap(bm3, sprite3.x, sprite3.y, null);
}
}

游戏活动.java

public class GameActivity extends Activity implements OnTouchListener {
private static final int FRAME_RATE = 20;
long startTime;
int timerCount = 0;
int score = 0;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);
    h.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                            initGfx();
                    }
     }, 1000);
}
synchronized public void initGfx() {
    Point p1, p2;
    p1 = getStartPoint();
    ((GameBoard)findViewById(R.id.the_canvas)).setSprite1(p1.x, p1.y);
    ((View)findViewById(R.id.the_canvas)).setOnTouchListener(this);
  frame.removeCallbacks(frameUpdate);
  frame.postDelayed(frameUpdate, FRAME_RATE);
}
private Runnable frameUpdate = new Runnable() {
    @Override
    synchronized public void run() {
        if (state == GameState.Ready)
            updateReady();
        if (state == GameState.Running)
            updateRunning();
    }
    synchronized public void updateReady() {
        frame.removeCallbacks(frameUpdate);
        ((GameBoard)findViewById(R.id.the_canvas)).invalidate();
        startTime = System.nanoTime();  //set game start time
        frame.postDelayed(frameUpdate, FRAME_RATE);
    }
    synchronized public void updateRunning() {
        frame.removeCallbacks(frameUpdate);
        if (((GameBoard)findViewById(R.id.the_canvas)).didItHitTarget()) {
            score = score + 1;
//This works fine
            ((TextView)findViewById(R.id.score)).setText(Integer.toString(score));
            Point p1;
            p1 = getStartPoint();
            ((GameBoard)findViewById(R.id.the_canvas)).setSprite1(p1.x, p1.y);
        }
        float deltaTime = (System.nanoTime() - startTime) / 100000000000.0f;
        int j = (int) deltaTime;
        if ((int)deltaTime > timerCount) {
            timerCount = timerCount + 1;
//This works in debug but does not update live
((TextView)findViewById(R.id.countdown)).setText(Integer.toString(timerCount));
            Log.i(TAG, "Updating countdown");
        }
        ((GameBoard)findViewById(R.id.the_canvas)).invalidate();
        frame.postDelayed(frameUpdate, FRAME_RATE);
    }
};
4

1 回答 1

0

This was my solution in case anyone interested (or can still suggest better way!). Going from blackbelt's point that certain parts of the code are simply not being entered, I thought that, although I couldn't find the reason, it must be something to do with the complexity of the timer clock combined with android's thread handling. So I created the timer using a separate thread, as in code here: Android update TextView in Thread and Runnable

于 2013-06-04T15:24:34.760 回答