Search code examples
javaandroidfunctiontextviewandroid-animation

Why is the text in TextViews changing two times when I am calling it only once at a time?


I know setText just changes the text only once but I can't seem to find the reason why the text in it changes before I move on to the next question in the quizActivity

What I have made is an app with one activity in it which has a quiz in it, a question is displayed along with 4 options. When the user selects an option, if that option is correct then it becomes green and red otherwise and additionally, I then open a dialog box showing whether the answer was right or wrong and then the question is changed when the user clicks Next on the dialog box.

But what is happening that when the user selects an option, in between the process of clicking the option and then clicking next on the dialog box, the text in the questions and the options changes and I can't seem to figure out why is that happening. In total, the question and options change two times when they should change only once, the unexpected change is when the user clicks on an option and the dialog box opens.

Here is a video that describes the issue

Here's the code:

@Override
    public void onClick(View view) {

        int selectedOption = 0;

        switch (view.getId()) {

            case R.id.option_1_tile:
                selectedOption = 1;
                break;
            case R.id.option_2_tile:
                selectedOption = 2;
                break;
            case R.id.option_3_tile:
                selectedOption = 3;
                break;
            case R.id.option_4_tile:
                selectedOption = 4;
                break;

            default:

        }

        checkAnswer(selectedOption, view);
    }

Here's the function which checks the answer:

private void checkAnswer(int selectedOption, View view) {

        if (selectedOption == selected_questions.get(quesNum).getAnswer()) {
            //Right Answer
            (view).setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
            quizReference.child(selected_questions.get(quesNum).getId()).child("correct_attempts").setValue(String.valueOf(Integer.valueOf(selected_questions.get(quesNum).getCorrect_attempts()) + 1));
            quizReference.child(selected_questions.get(quesNum).getId()).child("total_attempts").setValue(String.valueOf(Integer.valueOf(selected_questions.get(quesNum).getTotal_attempts()) + 1));
            score++;
            correctDialog();

        } else {
            //Wrong Answer
            (view).setBackgroundTintList(ColorStateList.valueOf(Color.RED));

            quizReference.child(selected_questions.get(quesNum).getId()).child("total_attempts").setValue(String.valueOf(Integer.valueOf(selected_questions.get(quesNum).getTotal_attempts()) + 1));

            switch (selected_questions.get(quesNum).getAnswer()) {
                case 1:
                    options[0].setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
                    break;
                case 2:
                    options[1].setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
                    break;
                case 3:
                    options[2].setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
                    break;
                case 4:
                    options[3].setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
                    break;

            }

            wrongDialog ();

        }


    }

Here's the function which changes the question:

 private void changeQuestion() {
    
            resetColor ();
    
            if (quesNum < selected_questions.size() - 1) {
    
                quesNum++;
    
                playAnim(question, 0, 0);
                playAnim(option1_text, 0, 1);
                playAnim(option2_text, 0, 2);
                playAnim(option3_text, 0, 3);
                playAnim(option4_text, 0, 4);
    
                qCount.setText(String.valueOf(quesNum + 1) + "/" + String.valueOf(selected_questions.size()));
    
    
            } else {
                // Go to Score Activity
                Intent intent = new Intent(quizActivity.this, scoreActivity.class);
                intent.putExtra("SCORE", String.valueOf(score) + "/" + String.valueOf(selected_questions.size()));
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                startActivity(intent);
    
            }
    
    
        }

Here's the function which sets the text and animation:

private void playAnim(final View view, final int value, final int viewNum) {
        view.animate().alpha(value).scaleX(value).scaleY(value).setDuration(500)
                .setStartDelay(100).setInterpolator(new DecelerateInterpolator())
                .setListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        if (value == 0) {
                            switch (viewNum) {
                                case 0:
                                    ((TextView) view).setText(selected_questions.get(quesNum).getQuestion());
                                    break;
                                case 1:
                                    ((TextView) view).setText(selected_questions.get(quesNum).getOption1());
                                    break;
                                case 2:
                                    ((TextView) view).setText(selected_questions.get(quesNum).getOption2());
                                    break;
                                case 3:
                                    ((TextView) view).setText(selected_questions.get(quesNum).getOption3());
                                    break;
                                case 4:
                                    ((TextView) view).setText(selected_questions.get(quesNum).getOption4());
                                    break;

                            }


                            if (viewNum != 0)
                                (view).setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#E99C03")));


                            playAnim(view, 1, viewNum);

                        }

                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {

                    }
                });

    }

Here's the code for the dialog boxes:

 public void wrongDialog() {
        final Dialog dialogWrong = new Dialog(quizActivity.this);
        dialogWrong.requestWindowFeature(Window.FEATURE_NO_TITLE);
        if (dialogWrong.getWindow() != null) {
            ColorDrawable colorDrawable = new ColorDrawable(Color.TRANSPARENT);
            dialogWrong.getWindow().setBackgroundDrawable(colorDrawable);
        }
        dialogWrong.setContentView(R.layout.dialog_wrong);
        dialogWrong.setCancelable(false);
        dialogWrong.show();



        TextView wrongText = (TextView) dialogWrong.findViewById(R.id.wrongText);
        Button buttonNext = (Button) dialogWrong.findViewById(R.id.dialogNext);

        //OnCLick listener to go next que
        buttonNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //This will dismiss the dialog
                dialogWrong.dismiss();

                //reset the color of buttons back to white
                resetColor();

                //Change question
                changeQuestion();


            }
        });
    }

    public void correctDialog() {
        final Dialog dialogCorrect = new Dialog(quizActivity.this);
        dialogCorrect.requestWindowFeature(Window.FEATURE_NO_TITLE);
        if (dialogCorrect.getWindow() != null) {
            ColorDrawable colorDrawable = new ColorDrawable(Color.TRANSPARENT);
            dialogCorrect.getWindow().setBackgroundDrawable(colorDrawable);
        }
        dialogCorrect.setContentView(R.layout.dialog_correct);
        dialogCorrect.setCancelable(false);
        dialogCorrect.show();

     


        TextView correctText = (TextView) dialogCorrect.findViewById(R.id.correctText);
        Button buttonNext = (Button) dialogCorrect.findViewById(R.id.dialogNext);

        //OnCLick listener to go next que
        buttonNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //This will dismiss the dialog
                dialogCorrect.dismiss();

                //reset the color of buttons back to white
                resetColor();

                //it will increment the question number
                changeQuestion();


            }
        });
    }

I have tried to explain it to my best ability though I would be glad to answer any additional information/code you may want. Also, this is the link for the project if you have the time to run it and understand the problem better.


Solution

  • I have checked your code. you have placed an addValueEventListener in setUpdates method. When you select an option, you update the firestore database by setting fields like total attempts. As a result, eventListener gets triggered and "selectQuestionSet" function is called.

    Hence, every time you select an option, selectQuestionSet function is called. You should make sure that its called only once at the start.