【问题标题】:How can you wait between two events in java?你怎么能在java中的两个事件之间等待?
【发布时间】:2021-05-04 01:10:28
【问题描述】:

我正在创建一个琐事应用程序。我希望在用户单击答案后立即出现正确/错误动画,然后在 3 秒后自动切换问题(淡入下一个问题)。我尝试使用 Thread.sleep(3000) 执行此操作,但整个程序冻结。到目前为止,这是我的代码:

binding.buttonTrue.setOnClickListener(view -> {
            checkAnswer(true);
            updateQuestion();
            //these two calls invoke right/wrong animation

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            changeTheQuestion();
            //this invokes fade animation

        });

如何在这两个动画之间添加一段时间?谢谢!

完整代码: 包 com.bawp.trivia;

import android.graphics.Color;
import android.media.AudioAttributes;
import android.media.SoundPool;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.bawp.trivia.data.Repository;
import com.bawp.trivia.databinding.ActivityMainBinding;
import com.bawp.trivia.model.Question;
import com.google.android.material.snackbar.Snackbar;

import java.util.ArrayList;
import java.util.List;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

public class MainActivity extends AppCompatActivity {

    List<Question> questionList;
    Handler mHandler;
    private ActivityMainBinding binding;
    private int currentQuestionIndex = 0;
    SoundPool soundPool;
    private int sound1, sound2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        questionList = new Repository().getQuestions(questionArrayList -> {
                    binding.questionTextview.setText(questionArrayList.get(currentQuestionIndex)
                            .getAnswer());

                    updateCounter(questionArrayList);
                }

        );

        mHandler = new Handler();


        binding.buttonNext.setOnClickListener(view -> {

            currentQuestionIndex = (currentQuestionIndex + 1) % questionList.size();
            updateQuestion();

        });


        binding.buttonTrue.setOnClickListener(view -> {

          checkAnswer(true);
          updateQuestion();

          new Handler().postDelayed(new Runnable() {
              @Override
              public void run() {
                  changeTheQuestion();
              }
          }, 3000);

        });




        binding.buttonFalse.setOnClickListener(view -> {

            checkAnswer(true);
            updateQuestion();

            new Handler().postDelayed(new Runnable() {
                public void run() {
                    changeTheQuestion();
                }
            }, 3000);



        });



        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                .build();

        soundPool = new SoundPool.Builder()
                .setMaxStreams(4)
                .setAudioAttributes(audioAttributes)
                .build();

        sound1 = soundPool.load(this, R.raw.correct, 1);
        sound2 =  soundPool.load(this, R.raw.wrong, 1);


    }

    private void checkAnswer(boolean userChoseCorrect) {
        boolean answer = questionList.get(currentQuestionIndex).isAnswerTrue();
        int snackMessageId = 0;
        if (userChoseCorrect == answer) {
            snackMessageId = R.string.correct_answer;
            fadeAnimation();
            soundPool.play(sound1, 1, 1, 0, 0, 1);
        } else {
            snackMessageId = R.string.incorrect;
            shakeAnimation();
            soundPool.play(sound2, 1, 1, 0, 0, 1);
        }
        Snackbar.make(binding.cardView, snackMessageId, Snackbar.LENGTH_SHORT)
                .show();

    }

    private void updateCounter(ArrayList<Question> questionArrayList) {
        binding.textViewOutOf.setText(String.format(getString(R.string.text_formatted),
                currentQuestionIndex, questionArrayList.size()));
    }

    private void fadeAnimation() {
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
        alphaAnimation.setDuration(300);
        alphaAnimation.setRepeatCount(1);
        alphaAnimation.setRepeatMode(Animation.REVERSE);


        binding.cardView.setAnimation(alphaAnimation);

        alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                binding.questionTextview.setTextColor(Color.GREEN);
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                binding.questionTextview.setTextColor(Color.WHITE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });





    }
    private void changeTheQuestion() {
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
        alphaAnimation.setDuration(300);
        alphaAnimation.setRepeatCount(1);
        alphaAnimation.setRepeatMode(Animation.REVERSE);




        binding.cardView.setAnimation(alphaAnimation);

        alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                binding.questionTextview.setTextColor(Color.BLUE);
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                currentQuestionIndex = (currentQuestionIndex + 1) % questionList.size();
                updateQuestion();
                binding.questionTextview.setTextColor(Color.WHITE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });





    }

    private void updateQuestion() {
        String question = questionList.get(currentQuestionIndex).getAnswer();
        binding.questionTextview.setText(question);
        updateCounter((ArrayList<Question>) questionList);
    }

    private void shakeAnimation() {
        Animation shake = AnimationUtils.loadAnimation(MainActivity.this,
                R.anim.shake_animation);
        binding.cardView.setAnimation(shake);


        shake.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                binding.questionTextview.setTextColor(Color.RED);

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                binding.questionTextview.setTextColor(Color.WHITE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });






    }

    


}

Repository.java:

package com.bawp.trivia.data;

import android.util.Log;

import com.android.volley.Request;
import com.android.volley.toolbox.JsonArrayRequest;
import com.bawp.trivia.controller.AppController;
import com.bawp.trivia.model.Question;

import org.json.JSONException;

import java.util.ArrayList;
import java.util.List;

public class Repository {
    ArrayList<Question> questionArrayList = new ArrayList<>();

    String url = "https://raw.githubusercontent.com/curiousily/simple-quiz/master/script/statements-data.json";

    public List<Question> getQuestions( final AnswerListAsyncResponse callBack) {

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET,
                url, null, response -> {
            for (int i = 0; i < response.length(); i++) {

                try {
                    Question question = new Question(response.getJSONArray(i).get(0).toString(),
                            response.getJSONArray(i).getBoolean(1));

                    //Add questions to arraylist/list
                    questionArrayList.add(question);

                    //Log.d("Hello", "getQuestions: " + questionArrayList);


                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            if (null != callBack) callBack.processFinished(questionArrayList);



        }, error -> {

        });

        AppController.getInstance().addToRequestQueue(jsonArrayRequest);

        return questionArrayList;
    }

}

【问题讨论】:

  • 删除了android-studio 标签。此标签用于有关 Android Studio 产品的问题/疑问。您的问题是一个通用的 Android 问题,与 Android Studio 无关。
  • 好的,谢谢。知道如何解决这个问题吗?谢谢。

标签: java android multithreading button


【解决方案1】:

您不能在主 (UI) 线程上调用 Thread.sleep()。这将冻结您的应用并导致您的应用因 ANR(应用程序无响应)错误而崩溃。

您可以只发布一个Runnable,它将在一段时间后运行一段代码。像这样的:

new Handler().postDelayed(new Runnable() {
    public void run() {
        changeTheQuestion();
    }
}, 3000);

【讨论】:

  • 嗨,我确实试过这个,但是在继续下一个问题之前,它开始出现故障和闪烁 3 次。有时它适用于问题,有时您必须多次单击答案才能继续。知道可能是什么原因造成的吗?谢谢。
  • 没有,但听起来您还有其他问题。这样做不应该导致那个问题。我将不得不看到更多的代码。也许显示你的代码changeQuestion()
  • 在 OP 中包含了完整的代码。谢谢。
  • 我假设问题出在您的动画中。如果您根本不拨打changeQuestion() 会发生什么?你还有这种闪烁/故障吗?
  • 您好,问题解决了。出于某种原因,在 changeTheQuestion() 中调用 updateQuestion() 把事情搞砸了。相反,我增加了索引,称为 changeTheQuestion(),然后是 updateQuestion(),一切正常。谢谢!
猜你喜欢
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多