在Timer完成或取消后运行代码

时间:2019-09-16 12:33:56

标签: java android timer timertask

enter image description here 遵循路径游戏说明:
在此游戏中,屏幕上有一些不可见的正方形(在我们的案例中为9),它们的随机序列开始出现在屏幕上(此处我们仅显示4)。并且用户必须按照屏幕上显示的顺序选择正方形。

有什么问题?
1.在显示过程中,不允许用户选择正方形。我可以禁用按钮,但是如何在计时器结束后启用它们?我找不到postLaunch或timerCanceled事件来再次启用按钮进行选择吗?
2.用户玩完游戏后,游戏应在1秒内自动重新开始。如果我在setBackgroundColor()之后使用Thread.sleep(1000),它将给我1秒,但忽略setBackground()。我希望用户在游戏重置之前看到错误的答案(背景颜色不正确)。

代码:

// allSquares, generatedSquares,generationSpeed can be used to change game difficulty
int allSquares = 9;
int generatedSquares = 4;
int generationSpeed = 500;
Button[] buttons = new Button[allSquares];
@IdRes
int[] ids = {R.id.b1, R.id.b2, R.id.b3, R.id.b4, R.id.b5, R.id.b6, R.id.b7, R.id.b8, R.id.b9};
Button bGenerate;
List<Integer> randomOrder;
int selectedSquare = 0;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    bGenerate = findViewById(R.id.bGenerate);
    bGenerate.setOnClickListener(this);
}

private void runAlgorithm()
{
    // initiate + invisible all squares
    for (int i = 0; i < allSquares; i++)
    {
        buttons[i] = findViewById(ids[i]);
        buttons[i].setAlpha(0.0f);
        buttons[i].setOnClickListener(this);
        buttons[i].setBackgroundColor(getResources().getColor(R.color.squareColor));
        buttons[i].setEnabled(false);
    }

    // generate random sequence
    randomOrder = new ArrayList<>();
    randomOrder.clear();
    Random random = new Random();
    while (randomOrder.size() < generatedSquares)
    {
        int generatedNumber = random.nextInt(allSquares);
        if (!randomOrder.contains(generatedNumber))
        {
            randomOrder.add(generatedNumber);
            Log.i("FollowThePath", generatedNumber + "");
        }
    }

    // show random sequence by order
    final int[] counter = {0};
    selectedSquare = 0;
    final Timer timer = new Timer();
    timer.schedule(new TimerTask()
    {
        @Override
        public void run()
        {
            buttons[randomOrder.get(counter[0])].setAlpha(1.0f);
            counter[0]++;
            if (counter[0] == generatedSquares)
            {
                timer.cancel();
            }
        }
    }, 0, generationSpeed);
    // Bug 1: need to enable buttons after timer finishes, user should not be allowed to choose a square during square reveal
}



@Override
public void onClick(View v)
{
    if (v.getId() == R.id.bGenerate)
        runAlgorithm();
    else
    {
        Log.i("FollowThePath", v.getTag().toString() + "       " + randomOrder.get(selectedSquare));
        if (v.getTag().toString().equals(randomOrder.get(selectedSquare).toString()))
        {
            v.setBackgroundColor(getResources().getColor(R.color.correctColor));
            v.setEnabled(false);
            selectedSquare++;
        } else
        {
            // Game Over
            Toast.makeText(this, "You failed.", Toast.LENGTH_SHORT).show();
            // Bug: setBackground executes so fast
            v.setBackgroundColor(getResources().getColor(R.color.incorrectColor));
            // Bug 2: we need a delay here, so that user sees the incorrect color and gets ready for next game
            // Thread.sleep(1000) ignores the color change, it means user can't see incorrectColor even if i add a Thread.sleep after that
            // starting a new game
            runAlgorithm();
        }
        if (selectedSquare == generatedSquares)
        {
            // Succeeded
            // Toast.makeText(this,"You did it.",Toast.LENGTH_SHORT).show();
            // run a new game
            runAlgorithm();
        }
    }
}

private void enableAllButtons(boolean enable)
{
    for (int i = 0; i < allSquares; i++)
    {
        buttons[i].setEnabled(enable);
    }
}

1 个答案:

答案 0 :(得分:1)

要解决您的第一个问题,由于完成TimerTask的唯一方法是根据条件counter[0] == generatedSquares取消@Override public void run() { buttons[randomOrder.get(counter[0])].setAlpha(1.0f); counter[0]++; if (counter[0] == generatedSquares) { runOnUiThread(new Runnable() { @Override public void run() { enableAllButtons(true); } }); timer.cancel(); } } ,因此您要做的就是这样:

Thread.sleep(1000)

对于第二个问题,可能不会显示颜色变化,因为重新启动算法开始得太快,并且所有这些都在UI线程上,因此使用runAlgorithm()并没有帮助。尝试将Handler handler = new Handler(); Runnable r = new Runnable() { public void run() { //what ever you do here will be done after 500 mili seconds delay. runAlgorithm(); } }; handler.postDelayed(r, 500); 调用包装为以下内容:

{{1}}

希望该方法能正常工作,因为我无法对其进行测试。

相关问题