December 15, 2016

Android Count Down Timer Tutorial

By admin


A countdown is a sequence of backward counting to indicate the time remaining before an event is scheduled to occur. To achieve countdown Android comes with a built-in CountDownTimer class for constructing CountDownTimers. Its easy to use, efficient and works.This class is an abstract class whose methods need to be overridden to implement it in our project.

Let’s Get it Working

In this tutorial we are going to learn the basic usage of CountDownTimer. To really understand the usage of count down timer we will create an app. This app show the circular progress bar , time and start/stop image to control the count down timer.

Count Down Timer App

Count Down Timer App

DownloadCode
 
github

Basic Usage

Implementing a Count Down Timer in your app won’t take more than two steps. First you need to create an object of in-built abstract class named CountDownTimer. This class is used to Schedule a countdown until a time in the future, with regular notifications on intervals along the way.

CountDownTimer countDownTimer = new CountDownTimer(60000, 1000) {

            public void onTick(long millisUntilFinished) {

                mTextView.setText("Seconds Remaining: " + millisUntilFinished / 1000);
            }

            public void onFinish() {

                mTextView.setText("Time Up!");
                
            }
        };

Second you have to start the count down timer via invoking start() method.

countDownTimer.start();

Step 1) Creating New Project

Create a new project in Android Studio from File ⇒ New Project Fill the required information like project name and package name of the project. When it prompts you to select the default activity, select Empty Activity and proceed.

Step 2) Defining strings,colors and styles

2.1 Add the below string values to the strings.xml located in res ⇒ values ⇒ strings.xml.

<resources>
    <string name="app_name">Count Down Timer</string>
    <string name="hint_minute">Minute</string>
    <string name="message_minutes">Please Enter Minutes...</string>
</resources>

2.2 Add the below color values to the colors.xml located in res ⇒ values ⇒ colors.xml.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#1E2538</color>
    <color name="colorPrimaryDark">#0E121B</color>
    <color name="colorAccent">#F5FA55</color>
    <color name="colorBackground">#151B29</color>
    <color name="colorYellow">#F5FA55</color>
</resources>

2.3 Add the below style values to the styles.xml located in res ⇒ values ⇒ styles.xml.

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

Step 3) Adding drawable

Before creating layout we have to write custom drawable xmls for circular progress bar .And also need some images for start, stop and reset icon.
3.1 Create new drawable resource file by right click on drawable ⇒ New ⇒ Drawable resource file name it drawable_circle_yellow.xml and add the below code to it. This file will create a yellow hollow circle of 10dp of thicknes.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadiusRatio="2.3"
    android:shape="ring"
    android:thickness="10dp"
    android:useLevel="true">
    <solid android:color="@color/colorYellow" />
</shape>

3.2 Again Create new drawable resource file by right click on drawable ⇒ New ⇒ Drawable resource file name it drawable_circle_dark_blue.xml and add the below code to it. This file will create a blue hollow circle of 10dp of thicknes.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadiusRatio="2.3"
    android:shape="ring"
    android:thickness="10dp"
    android:useLevel="false">

    <solid android:color="@color/colorPrimaryDark" />

</shape>

3.3 Download the images zip. Unzip it and place all the images in drawable folder.

Step 4) Creating the layout

Now add the below code to activity_main.xml located in res ⇒ layout ⇒ activity_main.xml. This code will create a view show above in the screen shot i.e a circular progress bar to show the time elapsed progress, input field to enter minutes, text field to show the time, start/stop and reset image to control the count down timer.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorBackground">

    <ProgressBar
        android:id="@+id/progressBarCircle"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="270dp"
        android:layout_height="270dp"
        android:layout_centerInParent="true"
        android:background="@drawable/drawable_circle_dark_blue"
        android:indeterminate="false"
        android:max="100"
        android:progress="100"
        android:progressDrawable="@drawable/drawable_circle_yellow"
        android:rotation="-90" />

    <EditText
        android:id="@+id/editTextMinute"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/textViewTime"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:gravity="center"
        android:hint="@string/hint_minute"
        android:inputType="number"
        android:maxLength="15"
        android:maxLines="1"
        android:minEms="5"
        android:text="1"
        android:textColor="@color/colorYellow"
        android:textColorHint="@color/colorYellow" />

    <TextView
        android:id="@+id/textViewTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="00:01:00"
        android:textColor="@color/colorYellow"
        android:textSize="40sp" />

    <ImageView
        android:id="@+id/imageViewReset"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_below="@+id/textViewTime"
        android:layout_centerInParent="true"
        android:layout_marginTop="30dp"
        android:src="@drawable/icon_reset"
        android:visibility="gone" />

    <ImageView
        android:id="@+id/imageViewStartStop"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_below="@+id/progressBarCircle"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:src="@drawable/icon_start" />

</RelativeLayout>





Step 5) Writing Code in MainActivity class

Now add the below code to MainActivity.java located in java ⇒ project’s package ⇒ MainActivity. Here i have written code to initialize views, added click listeners on it ,methods to control start stop reset functionality.

initViews() to intialize views.
initListeners() to initialize the click listeners.
setTimerValues() fetches the input minute value from the edit text, convert minutes to milliseconds that is required for count down timer.
startCountDownTimer() initializes the abstract class count down timer object with two implemented methods onTick(long milliSeconds) and onFinish(). onTick(long milliSeconds) Callback is fired on regular interval and onFinish() Callback is fired when the time is up. With count down timer object i started it by calling countDownTimer.start();
stopCountDownTimer() stops the count down timer by calling cancel() method.
startStop() contains start/stop functionality for count down timer and also make changes in views.
hmsTimeFormatter(long milliSeconds) convert the milliseconds to HH:mm:ss time format.

package com.androidtutorialshub.countdowntimer;

import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private long timeCountInMilliSeconds = 1 * 60000;

    private enum TimerStatus {
        STARTED,
        STOPPED
    }

    private TimerStatus timerStatus = TimerStatus.STOPPED;

    private ProgressBar progressBarCircle;
    private EditText editTextMinute;
    private TextView textViewTime;
    private ImageView imageViewReset;
    private ImageView imageViewStartStop;
    private CountDownTimer countDownTimer;


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

        // method call to initialize the views
        initViews();
        // method call to initialize the listeners
        initListeners();


    }

    /**
     * method to initialize the views
     */
    private void initViews() {
        progressBarCircle = (ProgressBar) findViewById(R.id.progressBarCircle);
        editTextMinute = (EditText) findViewById(R.id.editTextMinute);
        textViewTime = (TextView) findViewById(R.id.textViewTime);
        imageViewReset = (ImageView) findViewById(R.id.imageViewReset);
        imageViewStartStop = (ImageView) findViewById(R.id.imageViewStartStop);
    }

    /**
     * method to initialize the click listeners
     */
    private void initListeners() {
        imageViewReset.setOnClickListener(this);
        imageViewStartStop.setOnClickListener(this);
    }

    /**
     * implemented method to listen clicks
     *
     * @param view
     */
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.imageViewReset:
                reset();
                break;
            case R.id.imageViewStartStop:
                startStop();
                break;
        }
    }

    /**
     * method to reset count down timer
     */
    private void reset() {
        stopCountDownTimer();
        startCountDownTimer();
    }


    /**
     * method to start and stop count down timer
     */
    private void startStop() {
        if (timerStatus == TimerStatus.STOPPED) {

            // call to initialize the timer values
            setTimerValues();
            // call to initialize the progress bar values
            setProgressBarValues();
            // showing the reset icon
            imageViewReset.setVisibility(View.VISIBLE);
            // changing play icon to stop icon
            imageViewStartStop.setImageResource(R.drawable.icon_stop);
            // making edit text not editable
            editTextMinute.setEnabled(false);
            // changing the timer status to started
            timerStatus = TimerStatus.STARTED;
            // call to start the count down timer
            startCountDownTimer();

        } else {

            // hiding the reset icon
            imageViewReset.setVisibility(View.GONE);
            // changing stop icon to start icon
            imageViewStartStop.setImageResource(R.drawable.icon_start);
            // making edit text editable
            editTextMinute.setEnabled(true);
            // changing the timer status to stopped
            timerStatus = TimerStatus.STOPPED;
            stopCountDownTimer();

        }

    }

    /**
     * method to initialize the values for count down timer
     */
    private void setTimerValues() {
        int time = 0;
        if (!editTextMinute.getText().toString().isEmpty()) {
            // fetching value from edit text and type cast to integer
            time = Integer.parseInt(editTextMinute.getText().toString().trim());
        } else {
            // toast message to fill edit text
            Toast.makeText(getApplicationContext(), getString(R.string.message_minutes), Toast.LENGTH_LONG).show();
        }
        // assigning values after converting to milliseconds
        timeCountInMilliSeconds = time * 60 * 1000;
    }

    /**
     * method to start count down timer
     */
    private void startCountDownTimer() {

        countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {

                textViewTime.setText(hmsTimeFormatter(millisUntilFinished));

                progressBarCircle.setProgress((int) (millisUntilFinished / 1000));

            }

            @Override
            public void onFinish() {

                textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
                // call to initialize the progress bar values
                setProgressBarValues();
                // hiding the reset icon
                imageViewReset.setVisibility(View.GONE);
                // changing stop icon to start icon
                imageViewStartStop.setImageResource(R.drawable.icon_start);
                // making edit text editable
                editTextMinute.setEnabled(true);
                // changing the timer status to stopped
                timerStatus = TimerStatus.STOPPED;
            }

        }.start();
        countDownTimer.start();
    }

    /**
     * method to stop count down timer
     */
    private void stopCountDownTimer() {
        countDownTimer.cancel();
    }

    /**
     * method to set circular progress bar values
     */
    private void setProgressBarValues() {

        progressBarCircle.setMax((int) timeCountInMilliSeconds / 1000);
        progressBarCircle.setProgress((int) timeCountInMilliSeconds / 1000);
    }


    /**
     * method to convert millisecond to time format
     *
     * @param milliSeconds
     * @return HH:mm:ss time formatted string
     */
    private String hmsTimeFormatter(long milliSeconds) {

        String hms = String.format("%02d:%02d:%02d",
                TimeUnit.MILLISECONDS.toHours(milliSeconds),
                TimeUnit.MILLISECONDS.toMinutes(milliSeconds) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliSeconds)),
                TimeUnit.MILLISECONDS.toSeconds(milliSeconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliSeconds)));

        return hms;


    }


}
Count Down Timer

Count Down Timer

DownloadCode
 
github

Enjoy Coding and Share Knowledge