What is the best way to implement the timer?

60 views Asked by At

I'm writing an Android quiz app that needs to show a timer. What is the best way to implement the timer? I'm new to android and this is my first app. I tried using Handlers. This works but doesn't seem to be efficient.

public class PertanyaanActivity extends Activity
{

    private Handler progressBarHandler = new Handler();
    ProgressBar progressBar;
    TextView progressText;
    PertanyaanData mQuestionData;
    JawabanData mAnswerData;

    private int mCategoryId;
    private Map<Integer, Pertanyaan> mQuestions;
    private Map<Integer, Jawaban> mAnswers;

    private List<Integer> mQuestionIndexList;
    private int mNextQuestionIndex = 0;

    private int mTotalQuestions = 0;
    private int mQuestionsAnswered = 0;
    private int mCorrectAnswers = 0;

    private Pertanyaan mCurrentQuestion;

    private List<Button> answerButtons;

    private LinearLayout.LayoutParams mAnswerButtonLayout;

  //  private TextView mViewHeader;
    private ScrollView mQuestionScrollView;
    private TextView mQuestionText;
    private LinearLayout mAnswersFrame;
    private TextView mQuestionDescriptionText;
   // private Button mNextQuestionButton;
  //  private Button mCompleteButton;
    private int max_salah = 0;
    private  int progressBarStatus = 0;
    private long fileSize = 0;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.question);
        mCategoryId = getIntent().getIntExtra("categoryId", 0);

        Log.i(Constants.APP_LOG_NAME, "Getting question for category ID " + mCategoryId);

        mAnswerButtonLayout = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        mAnswerButtonLayout.setMargins(30, 20, 30, 0);

       // mViewHeader = (TextView)findViewById(R.id.viewHeader);
        mQuestionScrollView = (ScrollView)findViewById(R.id.questionScrollView);
        mQuestionText = (TextView)findViewById(R.id.questionText);
        mAnswersFrame = (LinearLayout)findViewById(R.id.answersFrame);

        progressText=(TextView)findViewById(R.id.progressText);
        progressBar= (ProgressBar) findViewById(R.id.ProgressBar01);
      //  progressBar.setProgress(0);
        //progressBar.setMax(100);
        waktu();
        //mQuestionDescriptionText = (TextView)findViewById(R.id.questionDescriptionText);
     //   mNextQuestionButton = (Button)findViewById(R.id.nextQuestionButton);
        //mCompleteButton = (Button)findViewById(R.id.completeButton);

        mQuestionData = new PertanyaanData(this);
        mAnswerData = new JawabanData(this);

        mQuestions = mQuestionData.getQuestionsByCategoryId(mCategoryId);

        mQuestionIndexList = new ArrayList<Integer>();

        for (int questionId : mQuestions.keySet())
        {
            mQuestionIndexList.add(questionId);
        }

        Collections.shuffle(mQuestionIndexList);

        if (mQuestionIndexList.size() > (Constants.MAX_QUESTIONS_PER_ROUND))
        {
            mQuestionIndexList = mQuestionIndexList.subList(0, Constants.MAX_QUESTIONS_PER_ROUND);
        }

        mTotalQuestions = mQuestionIndexList.size();

        Log.i(Constants.APP_LOG_NAME, "Total questions: " + mTotalQuestions);

        if (mTotalQuestions > 0)
        {
            displayNextQuestion();
        }
        else
        {
            Log.e(Constants.APP_LOG_NAME, "No questions found for category ID " + mCategoryId);
        }

        setVolumeControlStream(AudioManager.STREAM_MUSIC);
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();

        if (mQuestionData != null)
        {
            mQuestionData.close();
        }

        if (mAnswerData != null)
        {
            mAnswerData.close();
        }
    }

    /**
     * Displays the next available question in the current trivia round.
     */
    public void displayNextQuestion()
    {
        // Reset ScrollView position.
        mQuestionScrollView.scrollTo(0, 0);

        waktu();
        mCurrentQuestion = getNextQuestion();

        String headerText = getString(R.string.question)
                + " " + mNextQuestionIndex
                + " " + getString(R.string.of)
                + " " + mTotalQuestions;

        //mViewHeader.setText(headerText);

        //nyalakanWaktu();
        //waktu();
        displayQuestion(mCurrentQuestion);

       // mQuestionDescriptionText.setVisibility(View.GONE);
       // mNextQuestionButton.setVisibility(View.GONE);
    }

    /**
     * Gets the next available question in the current trivia round.
     *
     * @return Question - The instance of the next available question.
     */
    private Pertanyaan getNextQuestion()
    {
        int nextQuestionId = mQuestionIndexList.get(mNextQuestionIndex);

        Log.i(Constants.APP_LOG_NAME, "Got next question ID " + nextQuestionId);

        Pertanyaan question = mQuestions.get(nextQuestionId);

        if (question == null)
        {
            Log.w(Constants.APP_LOG_NAME, "Next question is null.");
        }

        mNextQuestionIndex++;

        return question;
    }

    /**
     * Displays a question on the screen.
     *
     * @param Question question - The question instance to display.
     */
    private void displayQuestion(Pertanyaan question)
    {
        if (question != null)
        {
            mAnswers = mAnswerData.getAnswersByQuestionId(question.getPertanyaanId());

            List<Integer> answerIndexList = new ArrayList<Integer>();

            for (int answerId : mAnswers.keySet())
            {
                answerIndexList.add(answerId);
            }

            Collections.shuffle(answerIndexList);

            mAnswersFrame.removeAllViews();

            mQuestionText.setText(question.getText());

            if (mAnswers != null)
            {
                answerButtons = new ArrayList<Button>();

                Jawaban answer = null;

                for (int answerId : answerIndexList)
                {
                    Log.i(Constants.APP_LOG_NAME, "Adding answer ID " + answerId);

                    answer = mAnswers.get(answerId);

                    Button answerButton = new Button(this);
                    answerButton.setId(answer.getJawabanId());
                    answerButton.setText(answer.getText());
                    answerButton.setBackgroundResource(R.drawable.button_normal);

                    answerButton.setOnClickListener(new View.OnClickListener()
                    {
                        public void onClick(View v)
                        {
                            disableAnswerButtons();

                            answerButtonClickHandler(v);
                        }
                    });

                    answerButtons.add(answerButton);

                    mAnswersFrame.addView(answerButton, mAnswerButtonLayout);
                }
            }
        }
        else
        {
            // TODO: Need to handle this in a more user-friendly way.
            mQuestionText.setText("Null question.");
        }
    }

    /**
     * Click handler for answer option buttons.
     * Determines the result of the user selecting an answer.
     *
     * @param View v - The current view.
     */
    public void answerButtonClickHandler(View v)
    {
        Jawaban answer = mAnswers.get(v.getId());

        if (answer != null)
        {
            mQuestionsAnswered++;

            if (answer.isCorrect())
            {
                mCorrectAnswers++;

                v.setBackgroundResource(R.drawable.answer_button_correct);

                Suara.playButtonClickSuccess();
            }
            else
            {
                max_salah++;
                v.setBackgroundResource(R.drawable.answer_button_incorrect);

                Suara.playButtonClickFailure();

            }

           // mQuestionDescriptionText.setText(mCurrentQuestion.getDescription());
            //mQuestionDescriptionText.setVisibility(View.VISIBLE);

            if (mNextQuestionIndex < mQuestionIndexList.size() && max_salah < 3)
            {
                //mNextQuestionButton.setVisibility(View.VISIBLE);


                //nyalakanWaktu();
                waktu();
                displayNextQuestion();
            }
            else
            {


                Intent i = new Intent(this, SummaryActivity.class);
                i.putExtra("categoryId", mCategoryId);
                i.putExtra("questionsAnswered", mQuestionsAnswered);
                i.putExtra("correctAnswers", mCorrectAnswers);
                startActivity(i);
                //mCompleteButton.setVisibility(View.VISIBLE);
            }
        }
    }

    /**
     * Click handler for the next question button.
     * Displays the next available question after current question is answered.
     *
     * @param View v - The current view.
     */
    public void nextQuestionButtonClickHandler(View v)
    {
        displayNextQuestion();

        Suara.playButtonClick();
    }

    /**
     * Click handler for the trivia round completion button.
     * Displays the round summary screen when clicked.
     *
     * @param View v - The current view.
     */
    public void completeButtonClickHandler(View v)
    {
        Intent i = new Intent(this, SummaryActivity.class);
        i.putExtra("categoryId", mCategoryId);
        i.putExtra("questionsAnswered", mQuestionsAnswered);
        i.putExtra("correctAnswers", mCorrectAnswers);
        startActivity(i);
    }

    /**
     * Disables all answer buttons.
     * Used after an answer is selected.
     */
    private void disableAnswerButtons()
    {
        Button answerButton = null;

        for (int i = 0; i < answerButtons.size(); i++)
        {
            answerButton = answerButtons.get(i);
            answerButton.setEnabled(false);
        }
    }

    public void nyalakanWaktu(){
        final Handler handler = new Handler();
        Timer timer = new Timer();
        TimerTask doAsynchronousTask = new TimerTask() {

            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        try {
                            progressBar.incrementProgressBy(1);
                            int stringProgress=progressBar.getProgress();
                            progressText.setText(stringProgress+"");
                        } catch (Exception e) {
                        }
                    }
                });
            }

        };timer.schedule(doAsynchronousTask, 0, 200);
        //audioBackground.stop();

    }
1

There are 1 answers

2
Meenaxi On

You can use CountDownTimer

     new CountDownTimer(30000, 1000) {

     public void onTick(long millisUntilFinished) {
         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     }

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();

I think its better to use CountDownTimer when you have time limit. In above sample 30000 is time limit and has interval of 1000 milliseconds. After 30 minutes the onfinish() will get called. and you can write your logic for time spent on onTick().

Better explained here