等待线程完成然后移动到下一个位置

时间:2016-03-27 12:58:18

标签: android multithreading android-toast

我正在尝试在屏幕上显示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();
    }

有关如何执行此操作的任何建议吗?

4 个答案:

答案 0 :(得分:2)

您可以确定吐司的可见性:

toast.getView().getWindowToken()

如果结果为null,则不再显示您的Toast,并且您可以运行任何所需的代码。

答案 1 :(得分:2)

this answer中所述,你可以开始一个等待Toast持续时间的线程:

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_SHORTToast.LENGTH_LONG只是标志,因此您必须对持续时间进行硬编码或将其保持为常量。持续时间为3.5秒(长)和2秒(短)。

如果你想操纵你的一些观点,你不能在另一个线程中执行此操作而不是&#34; main&#34; UI线程。因此,您必须实现一种回调/轮询机制,以便在SleepThread完成后收到通知。 查看this answer以了解有关此方法的几种方法。可能最容易理解和实施的是:

启动线程后,您可以通过调用thread.isAlive()来检查它是否仍然存在且正在运行。通过这种方式,您可以执行在线程运行时运行的while循环:

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

请注意,这不是最优雅的方式!检查上面提到的答案中的其他可能性,以获得更优雅的解决方案(尤其是最后一个与听众一起使用非常有趣且值得一读!)

答案 2 :(得分:0)

我的错误是因为我试图通过另一个线程访问UI元素,因此修改代码如下:

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();

做了这个伎俩。我希望我的回答可以帮助别人!!!

答案 3 :(得分: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,这个方法在主线程中被调用。