Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to add a timer to the actionbar on android?

I'd like a simple mm:ss timer to be displayed on my actionbar, be able to pick the number of minutes to start counting down from and then call a method once it's at 0. Is this possible and how?

like image 630
Omair Vaiyani Avatar asked Jul 02 '13 16:07

Omair Vaiyani


People also ask

How do you add action items to the action bar in Android?

All action buttons and other items available in the action overflow are defined in an XML menu resource. To add actions to the action bar, create a new XML file in your project's res/menu/ directory. The app:showAsAction attribute specifies whether the action should be shown as a button on the app bar.

What is main action bar in Android?

Android ActionBar is a menu bar that runs across the top of the activity screen in android. Android ActionBar can contain menu items which become visible when the user clicks the “menu” button. In general an ActionBar consists of the following four components: App Icon: App branding logo or icon will be displayed here.

What is timer in Android Studio?

A facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals. Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially.

What is the difference between appbar and toolbar in Android?

The key differences that distinguish the Toolbar from the ActionBar include: Toolbar is a View included in a layout like any other View. As a regular View , the toolbar is easier to position, animate and control. Multiple distinct Toolbar elements can be defined within a single activity.


2 Answers

I've managed to do that by adding a TextView to the Action Bar as an Action View in the menu, then updating it at regular intervals using a CountDownTimer.
(Tested on an Android 3.0 emulator, an Android 4.3 emulator and a real device running Android 4.3).

Here's the XML for the menu item. Note that actionViewClass="android.widget.TextVew"
(showAsAction and actionViewClass don't have the android namespace because I'm using the support action bar).

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:compatibility="http://schemas.android.com/apk/res-auto" >

    <item android:id="@+id/break_timer"
          android:title="@string/break_timer_title"
          compatibility:showAsAction="always"
          compatibility:actionViewClass="android.widget.TextView" />

</menu>

In onCreateOptionsMenu, I find the MenuItem and call getActionView to assign it to private TextView, timerText. I also apply some padding here, so that it's not right at the edge of the screen.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.break_timer, menu);

    MenuItem timerItem = menu.findItem(R.id.break_timer);
    timerText = (TextView) MenuItemCompat.getActionView(timerItem);

    timerText.setPadding(10, 0, 10, 0); //Or something like that...

    startTimer(30000, 1000); //One tick every second for 30 seconds
    return true;
}

I have a method called startTimer to start a CountDownTimer and update timerText in its onTick. I call startTimer from onCreateOptionsMenu to ensure that timerText is not accessed before it has been initialised. (Previously, I called startTimer from onCreate, but got a NullPointerException).

private void startTimer(long duration, long interval) {

    CountDownTimer timer = new CountDownTimer(duration, interval) {

        @Override
        public void onFinish() {
            //TODO Whatever's meant to happen when it finishes
        }

        @Override
        public void onTick(long millisecondsLeft) {
            int secondsLeft = (int) Math.round((millisecondsLeft / (double) 1000));
            timerText.setText(secondsToString(secondsLeft));
        }
    };

    timer.start();
}

I'm sure that anyone reading this will know a better way to convert an integer number of seconds to a timecode such as "00:00:00", but just in case I'll share the secondsToString method I used in onTick, above.

private String secondsToString(int improperSeconds) {

    //Seconds must be fewer than are in a day

    Time secConverter = new Time();

    secConverter.hour = 0;
    secConverter.minute = 0;
    secConverter.second = 0;

    secConverter.second = improperSeconds;
    secConverter.normalize(true);

    String hours = String.valueOf(secConverter.hour);
    String minutes = String.valueOf(secConverter.minute);
    String seconds = String.valueOf(secConverter.second);

    if (seconds.length() < 2) {
        seconds = "0" + seconds;
    }
    if (minutes.length() < 2) {
        minutes = "0" + minutes;
    }
    if (hours.length() < 2) {
        hours = "0" + hours;
    }

    String timeString = hours + ":" + minutes + ":" + seconds;
    return timeString;
}
like image 87
Matt Avatar answered Sep 17 '22 21:09

Matt


Menu xml

<item
                android:id="@+id/counter"
                android:title=""
                android:showAsAction="always">
</item>

**public boolean onCreateOptionsMenu(Menu menu)"

long timer = 10000;
public Boolean onCreateOptionsMenu(Menu menu) 
{
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu, menu);

       final MenuItem  counter = menu.findItem(R.id.counter);
        new CountDownTimer(timer, 1000) {

          public void onTick(long millisUntilFinished) {
             long millis = millisUntilFinished; 
             String  hms = (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))); 

             counter.setTitle(hms);
             timer = millis;

            }

        public void onFinish() {
             counter.setTitle("done!");
            }
         }.start();

         return  true;

 }
like image 43
Neeraj Kumar Avatar answered Sep 18 '22 21:09

Neeraj Kumar