таймер обратного отсчета в текстовом представлении

#android #textview #countdowntimer

#Android #textview #таймер обратного отсчета

Вопрос:

я написал этот код и хочу, чтобы при нажатии на btnGetPincode запускался таймер обратного отсчета на 60 секунд. но этого не произошло, и результат в textview = 00:00, и ничего не происходит. почему?

это мой код:

  btnGetPinCode.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
 btnGetPinCode.setClickable(false);
                btnGetPinCode.setBackgroundResource((R.drawable.button4));
                txtShowPinCode.setVisibility(View.VISIBLE);

                //initialize timer duration
                long duration = TimeUnit.MINUTES.toMillis(1);

                //initialize timer countdown timer
                new CountDownTimer(duration, 1000) {
                    @Override
                    public void onTick(long millisUntilFinished) {
                        String duration2 = String.format(Locale.ENGLISH, "d : d"
                                , TimeUnit.MILLISECONDS.toMinutes(1)
                                , TimeUnit.MILLISECONDS.toSeconds(1) -
                                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(1)));

                        //set converted time to textView
                        txtTimer.setVisibility(View.VISIBLE);
                        txtTimer.setText(duration2 "");
                        btnOk.setText(duration2);
                    }

                    @Override
                    public void onFinish() {
                        //when timer finished, hide text view
                        txtTimer.setVisibility(View.INVISIBLE);
                        btnGetPinCode.setBackgroundResource(R.drawable.button);
                        btnGetPinCode.setClickable(true);
                    }
                }.start();
    });
 

}

Ответ №1:

Проблема: вы устанавливаете 1 в каждом аргументе duration2 переменную, поэтому TextView никогда не будет изменен, вам нужно установить фактическое значение, которое изменяется при каждом тике таймера, которое является параметром onTick() метода >> millisUntilFinished

Измените таймер на:

 new CountDownTimer(duration, 1000) {
    @Override
    public void onTick(long millisUntilFinished) {
        String duration2 = String.format(Locale.ENGLISH, "d : d"
                , TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) //<<<<< change here
                , TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - //<<<< change here
                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))); //<<<<< change here

        //set converted time to textView
        txtTimer.setVisibility(View.VISIBLE);
        txtTimer.setText(duration2 "");
        btnOk.setText(duration2);
    }

    @Override
    public void onFinish() {
        //when timer finished, hide text view
        txtTimer.setVisibility(View.INVISIBLE);
        btnGetPinCode.setBackgroundResource(R.drawable.button);
        btnGetPinCode.setClickable(true);
    }
}.start();
 

Ответ №2:

Основная проблема заключается в расчете времени duration2

 //Declare timer
CountDownTimer cTimer = null;

cTimer  = new CountDownTimer(duration, 1000) {
@Override
public void onTick(long millisUntilFinished) {
    String duration2 = String.format(Locale.ENGLISH, "d : d"
            , TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) //Here is the problem
            , TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - //Here is the problem
                    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))); //<<<<< change here

    //set converted time to textView
    txtTimer.setVisibility(View.VISIBLE);
    txtTimer.setText(duration2 "");
    btnOk.setText(duration2);
}

@Override
public void onFinish() {
    //when timer finished, hide text view
    txtTimer.setVisibility(View.INVISIBLE);
    btnGetPinCode.setBackgroundResource(R.drawable.button);
    btnGetPinCode.setClickable(true);
 }
}.start();
 

Вам также необходимо очистить ссылки, чтобы предотвратить утечку памяти. Это должно вызываться cTtimer.cancel() всякий раз, когда вызывается onDestroy() / onDestroyView() в принадлежащем Activity / Fragment .

  void cancelTimer() {
  if(cTimer!=null)
    cTimer.cancel();
  }