2016-03-27 6 views
0

Я пытаюсь отобразить на экране Toast, и когда Toast исчезает, переходите к следующему вопросу. Я пробовал с Thread, но, похоже, не может справиться.Подождите, пока закончится нить, а затем переместитесь в следующую позицию.

Мой код:

next.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (getUserSelection()){ 
        position = position + 3; 
        if (position < questionsArray.size()) { 
         curName = questionsArray.get(position).getName(); 
         curArray = questionsArray.get(position).getAnswers(); 
         curIscorrect = questionsArray.get(position).getIscorrect(); 
         setupQuestionView(curName, curArray, curIscorrect); 
        } else { 
         StringGenerator.showToast(QuestionsActivity.this, "Your score : " + score + "/" + (questionsArray.size()/3)); 
        } 
       }else { 
        StringGenerator.showToast(QuestionsActivity.this, getString(R.string.noanswerselected)); 
       } 
      } 
     }); 

и getUserSelectionMethod:

private boolean getUserSelection() { 
     correct = (RadioButton)findViewById(group.getCheckedRadioButtonId()); 
     if (correct == null){ 
      return false; 
     }else { 
      correctAnswerText = correct.getText().toString(); 
      if (map.get(correctAnswerText).equals(Constants.CORRECTANSWER)) { 
       score++; 
       setCorrectMessage(); 
       return true; 
      } else { 
       setWrongMessage(); 
       return true; 
      } 
     } 
    } 

    private void setCorrectMessage() { 
     correctToast = new Toast(QuestionsActivity.this); 
     correctToastView = getLayoutInflater().inflate(R.layout.correct, (ViewGroup) findViewById(R.id.correctRootLayout)); 
     correctText = (TextView)correctToastView.findViewById(R.id.correctTextView); 
     correctText.setText(getString(R.string.correctAnswer)); 
     correctToast.setDuration(Toast.LENGTH_SHORT); 
     correctToast.setView(correctToastView); 
     correctToast.show(); 
     correctThread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       correctToast.cancel(); 
      } 
     }); 
     correctThread.start(); 
    } 

    private void setWrongMessage() { 
     wrongToast = new Toast(QuestionsActivity.this); 
     wrongToastView = getLayoutInflater().inflate(R.layout.wrong, (ViewGroup) findViewById(R.id.wrongRootLayout)); 
     wrongText = (TextView)wrongToastView.findViewById(R.id.wrongTextView); 
     wrongText.setText(getString(R.string.wrongAnswer)); 
     wrongToast.setDuration(Toast.LENGTH_SHORT); 
     wrongToast.setView(wrongToastView); 
     wrongToast.show(); 
     wrongThread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       wrongToast.cancel(); 
      } 
     }); 
     wrongThread.start(); 
    } 

Любое предложение о том, как это сделать?

+0

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

ответ

2

Вы можете определить видимость тост:

toast.getView().getWindowToken() 

Если результат нулевой, чем ваш тост не видно больше, и чем вы можете запустить любой код, который вы хотите.

2

, как указано в this answer вы можете запустить поток, который ждет продолжительность Тост:

Thread thread = new Thread(){ 
    @Override 
    public void run() { 
     try { 
      Thread.sleep(3500); // 3.5seconds! 
      // Do the stuff you want to be done after the Toast disappeared 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

Toast.LENGTH_SHORT и Toast.LENGTH_LONG только флаги, так что вы должны либо жесткий код продолжительности или держать их в постоянной. Длительность - 3,5 с (длинная) и 2 с (короткая).


Если вы хотите работать с некоторыми из ваших взглядов, вы не можете сделать это в другом потоке, чем «основной» UI нить. Таким образом, вы должны реализовать своего рода механизм обратного вызова/опроса, чтобы получить уведомление, когда SleepThread закончил. Отметьте this answer, чтобы узнать о нескольких путях для этого. Вероятно, проще всего понять и реализовать это:

После того, как вы начали тему, вы можете проверить, жив ли он еще и работает, позвонив по номеру thread.isAlive(). Таким образом, вы можете сделать то время цикла, который выполняется, когда поток выполняется:

// start your thread 
while(thread.isAlive()){} 
// continue the work. The other thread has finished. 

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

+0

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

+0

, что вы делаете после ' sleep'? Вы манипулируете любыми видами? – user187470

+0

yes Я устанавливаю текст для другого вопроса –

0

Моя ошибка была в том, что я пытался укрепить элементы пользовательского интерфейса через другую тему поэтому изменение кода выглядит следующим образом:

Thread thread = new Thread(new Runnable() { 
    @Override 
    public void run() { 
      try { 
       Thread.sleep(500); 
       QuestionsActivity.this.runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         moveToNextQuestion(); 
        } 
       }); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
    } 
}); 
thread.start(); 

сделал трюк. Надеюсь, мой ответ помогает кому-то !!!

0

Это потому, что класс Thread выполнен исключительно в фоновом режиме, и вам нужно управлять видом в Основной теме. Чтобы решить вашу проблему, просто замените Thread на AsynTask.

AsyncTask<Void,Void,Void> a = new AsyncTask<Void, Void, Void>() { 
      @Override 
      protected Void doInBackground(Void... params) { 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       return null; 
      } 

      @Override 
      protected void onPostExecute(Void aVoid) { 
       super.onPostExecute(aVoid); 
       correctToast.cancel(); 
      } 
     }; 
     a.execute(); 

Если вы посмотрите на мой код, который вы можете увидеть мой onPostExecute, этот метод вызывается в главном потоке.

+0

@ downvoters Пожалуйста, объясните свою сторону, чтобы отклонить мой ответ. Это поможет улучшить мою должность и сможет предоставить необходимые факты для будущих посетителей. В противном случае это может привести к ложному предположению. – Enzokie

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