@Bafrektez

Как заставить TextView работать только с одним таймером?

Добрый день. Проблема заключается в следующем: есть таймер, наследованный от CountDownTimer, его значение передается в TextView. Также присутствуют две кнопки - старт и пауза. При повторном нажатии на старт должен происходить перезапуск таймера. Это происходит, но весьма странным образом. TextView получает два и более значения одновременно и получается, что в одну секунду отображаются два и более значения одновременно. Как "убить" предыдущий таймер?

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 
    TextView mTimer;
    ImageButton startButton, pauseButton;
    int timeToEnd = 25000;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        mTimer = (TextView) findViewById(R.id.tv);
        startButton = (ImageButton) findViewById(R.id.startButton);
        pauseButton = (ImageButton) findViewById(R.id.pauseButton);
        startButton.setOnClickListener(this);
        pauseButton.setOnClickListener(this);
    }
 
    @Override
    public void onClick(View v) {
        final TimerClass timer = new TimerClass(timeToEnd, 1000);
        switch (v.getId()) {
            case R.id.startButton:
                startButton.setOnClickListener(this);
                timer.start();
                break;
            case R.id.pauseButton:
                pauseButton.setOnClickListener(this);
                timer.cancel();
        }
    }
 
    public class TimerClass extends CountDownTimer {
        public TimerClass(long milliFuture, long interval) {
            super(milliFuture, interval);
        }
 
        @Override
        public void onTick(long millisUntilFinished) {
            long millis = millisUntilFinished;
            String hhmmss = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
                    TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                    TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
            mTimer.setText(hhmmss);
        }
 
        @Override
        public void onFinish() {
            mTimer.setText("Completed");
        }
    }
 
    public void showSetting() {
        Intent intent = new Intent(this, Prefs.class);
        startActivity(intent);
    }
 
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuItem mi = menu.add(0, 0, 0, "Settings");
        mi.setIntent(new Intent(this, Prefs.class));
        return super.onCreateOptionsMenu(menu);
    }
}


P.S. Пробовал старую реализацию, там этой проблемы нет, но она мне не подходит, так как время должно задаваться извне и изменяться по желанию пользователя, а не быть строго фиксированным.

btnStart.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
  • Вопрос задан
  • 232 просмотра
Решения вопроса 1
Я бы на вашем месте так бы не делал, но ладно:

1)Зачем задаёте текст у TextView в таймере?Это нарушает принцип Деметры и абстракцию.Просто делаем переменную currentTime в интерфейсе класса и создаём геттер к нему:

public class TimerClass extends CountDownTimer {
    public String getCurrentTime() {
        return currentTime;
    }

    private String currentTime;

    public TimerClass(long milliFuture, long interval) {
        super(milliFuture, interval);
    }

    @Override
    public void onTick(long millisUntilFinished) {
        long millis = millisUntilFinished;
        String hhmmss = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
                TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
        currentTime = hhmmss;
    }

    @Override
    public void onFinish() {
        currentTime = "Completed";
    }
}


2)Теперь в классе активности создаём метод runTimer() с Handler, который будет
обновлять текст нашего TextView:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    TextView mTimer;
    Button startButton, pauseButton;
    int timeToEnd = 25000;
    final TimerClass timer = new TimerClass(timeToEnd, 1000);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTimer = (TextView) findViewById(R.id.tv);
        startButton = (Button) findViewById(R.id.startButton);
        pauseButton = (Button) findViewById(R.id.pauseButton);
        startButton.setOnClickListener(this);
        pauseButton.setOnClickListener(this);
        runTimer();
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.startButton:
                startButton.setOnClickListener(this);
                timer.start();
                break;
            case R.id.pauseButton:
                pauseButton.setOnClickListener(this);
                timer.cancel();
        }
    }

    private void runTimer() {


        final Handler handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {

                mTimer.setText(timer.getCurrentTime());
                handler.post(this);
            }
        });
    }

}


P.s
Очень костлявая реализация.Я бы сделал по-другому.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы