首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >等待线程完成,然后移动到下一个位置

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

Stack Overflow用户
提问于 2016-03-27 20:58:18
回答 4查看 185关注 0票数 0

我正在尝试在屏幕上显示一个Toast,当Toast消失时,然后进入下一个问题。我尝试过使用Thread,但似乎无法处理。

我的代码:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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();
    }

对如何做到这一点有什么建议吗?

EN

回答 4

Stack Overflow用户

发布于 2016-03-27 21:05:13

您可以确定toast可见性:

代码语言:javascript
复制
toast.getView().getWindowToken()

如果结果为空,那么您的toast将不可见,并且您可以运行任何您想要的代码。

票数 2
EN

Stack Overflow用户

发布于 2016-03-27 21:12:41

正如this answer中所述,您可以启动一个线程来等待Toast的持续时间:

代码语言:javascript
复制
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.5s (长)和2s (短)。

如果你想要操作你的一些视图,你不能在“主”UI线程之外的其他线程中操作。因此,您必须实现一种回调/轮询机制,以便在SleepThread完成时得到通知。请查看this answer,了解几种实现此目的的方法。其中最容易理解和实现的可能是:

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

代码语言:javascript
复制
// start your thread
while(thread.isAlive()){}
// continue the work. The other thread has finished.

请注意,这不是最优雅的方式!检查我上面提到的答案中的其他可能性,以获得更优雅的解决方案(特别是最后一个带有listeners的解决方案非常有趣,值得一读!)

票数 2
EN

Stack Overflow用户

发布于 2016-03-27 21:21:37

我的错误是因为我试图通过另一个线程访问UI元素,所以像这样修改代码:

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36247602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档