Android: как создать задержку в цикле при обновлении интерфейса

1

Это мой первый пост, так жаль, если я не правильно отформатирую свой вопрос. Я разрабатываю свое первое приложение для Android, и это карточная игра. Я разработал ту же карточную игру на С#, используя визуальную студию. В С#, чтобы имитировать действие и задержку при работе и т.д., Я спал поток в течение заданного промежутка времени, а затем вызывал метод Application.DoEvents(), который заставлял пользовательский интерфейс обновляться. Однако в java я не могу найти ответ на эту проблему.

Я отправлю код из моего метода deal(), который мне нужно отложить, поэтому похоже, что на самом деле карты раздаются по кругу, а не сразу, так как компьютер идет так быстро:

private void dealHelper()   {       Рука pCards = Referee.getHumanHand();

    //show all cards in rotating order
    for(int i=0; i<CARD_COUNT; i++)
    {
        ///////////////////////////////////////////////////////////////////////
        // load each card into their appropriate ImageViews and make visible //
        ///////////////////////////////////////////////////////////////////////

        //human player
        LoadCard(playerCards.get(i), pCards.getCard(i));
        playerCards.get(i).setVisibility(View.VISIBLE);
        playerCards.get(i).setPadding(1, 1, 1, 1);

        // allow discarded cards to be clickable
        discardCardImages.get(i).setPadding(1, 1, 1, 1);

        //computer 1
        computer1Cards.get(i).setImageResource(R.drawable.cardskin);
        computer1Cards.get(i).setVisibility(View.VISIBLE);

        //computer 2
        computer2Cards.get(i).setImageResource(R.drawable.cardskin);
        computer2Cards.get(i).setVisibility(View.VISIBLE);

        //computer 3
        computer3Cards.get(i).setImageResource(R.drawable.cardskin);
        computer3Cards.get(i).setVisibility(View.VISIBLE);
    }
}

Мне нужна небольшая задержка около 500 мс между каждой карточкой, отображаемой на экране, для имитации действия. Я искал и искал, и у меня нет решения, которое работает (или я понимаю). Любая помощь приветствуется.

Спасибо, Daniel

Теги:
loops
user-interface
delay

4 ответа

8

Используйте Handler с Runnable (который выполняет одну итерацию цикла в своем run()) и postDelayed(Runnable r, long delayMillis) для задержки. Подсчитайте итерации, чтобы вы знали, когда остановиться и использовать последний, чтобы removeCallbacks() и вызвать метод, чтобы сделать все, что нужно, как только сделка будет выполнена.


Что-то вроде

private final Handler mHandler = new Handler();
private int iLoopCount = 0;

private final Runnable rDealAndWait = new Runnable()
{
  public void run()
  {
    if (dealtAHand())
    {
      ++iLoopCount;
      mHandler.postAtTime(this, SystemClock.uptimeMillis() + DEAL_DELAY);
    }
    else
    {
      doAfterAllHandsDealt();
    }
  }
};


private boolean dealtAHand()
{
  if (i == CARD_COUNT) return false;

  //human player
  LoadCard(playerCards.get(iLoopCount), pCards.getCard(i));
  playerCards.get(iLoopCount).setVisibility(View.VISIBLE);
  playerCards.get(iLoopCount).setPadding(1, 1, 1, 1);

  // etc

  return true;
}

И затем в onCreate или wherever

  dealtAHand();
  mHandler.postAtTime(rDealAndWait, SystemClock.uptimeMillis() + DEAL_DELAY);

}

  • 0
    Я рассмотрел это решение, однако, полагаю, я не понял, как оно работало полностью. Когда я пытался реализовать каждую карточную сделку в Runnable, я получал сообщения о том, что он не может получить доступ к переменным вне метода (например, i) и что «i» не является статичным? Мне нужно «я», чтобы код знал, какую карту сдать. Я не был уверен в способе обойти это.
  • 0
    Вы должны иметь возможность объявить private int i поле private int i в окружающем классе и использовать его в runnable.
Показать ещё 3 комментария
0

пожалуйста, проверьте мой ответ здесь, это может вам помочь. не знаю его надлежащего пути или нет, но он работал у меня очень хорошо.

                @Override
                public void run() {
                    for(int i = 0;i<diceNum;i++){
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                            //do your Ui task here
                            }
                        });

                        try {

                            Thread.sleep(500);

                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
              }
            } 
  • 0
    Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится.
  • 1
    @SLBarth спасибо за предложение
0

Если вам ничего не удается из вышеперечисленных решений, попробуйте здесь CountDownTimer,

http://developer.android.com/reference/android/os/CountDownTimer.html

0

Попробуйте Thread.sleep(long millis). Вам придется поместить его в блок try/catch.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню