Skip to content
Kartikey Kushwaha edited this page Apr 22, 2017 · 27 revisions

An implementation with all the customization options used can be seen in the app available within the LinearTimer repository. To run this app, you need to clone the repo on your computer and then compile it via Android Studio.

Or, you can download the app from the Play Store.

Basics

First, you need to add LinearTimerView into your XML layout -

xmlns:timer="http://schemas.android.com/apk/res-auto"

<io.github.krtkush.lineartimer.LinearTimerView
    android:id="@+id/linearTimer"
    android:layout_centerHorizontal="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    timer:radius="20dp"
    timer:strokeWidth="3dp"/>

Note that "wrap_content" for height and width is recommended. Using other values might not lead correct rendering of the view.

After adding the view, here is how it is initialized and used -

LinearTimerView linearTimerView = (LinearTimerView)
                                    findViewById(R.id.linearTimer);

LinearTimer linearTimer = new LinearTimer.Builder()
            .linearTimerView(linearTimerView)
            .duration(10 * 1000)
            .build();

// Start the timer.
findViewById(R.id.startTimer).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
      linearTimer.startTimer();
    }
});

// Restart the timer.
findViewById(R.id.restartTimer).setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
        linearTimer.restartTimer();
      }
});

// Pause the timer
findViewById(R.id.pauseTimer).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
         try {
            linearTimer.pauseTimer();
         } catch (IllegalStateException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
         }
      }
 });

// Resume the timer
findViewById(R.id.resumeTimer).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
          try {
            linearTimer.resumeTimer();
          } catch (IllegalStateException e) {
              e.printStackTrace();
              Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
          }
      }
 });

// Reset the timer
findViewById(R.id.resetTimer).setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       try {
           linearTimer.resetTimer();
       } catch (IllegalStateException e) {
           e.printStackTrace();
           Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
       }
   }
});

List of methods available to control or get status of Linear Timer

Method Description Exception
1. startTimer() Start the timer. IllegalStateException
2. pauseTimer() Pause the timer. IllegalStateException
3. resumeTimer() Resume the timer from its pause position. IllegalStateException
4. resetTimer() Reset the timer to the starting angle; the timer will not start after reset. IllegalStateException
5. restartTimer() Restart the timer from the starting angle; the timer will start again. None
5. getState() Get current state of the timer. None

Start

Start may be called only when LinearTimer is in INITIALIZED state. A call to this method in any other state will throw an IllegalStateException. This method starts the linear timer. The user may start by:

    linearTimer.startTimer();

Pause

Pause may only be called when LinearTimer is in ACTIVE state. A call to this method in any other state will throw an IllegalStateException. Pausing the LinearTimer will stop the arc animation in its tracks and the counter as well, removing any callbacks registered. The user may access this feature by:



    linearTimer.pauseTimer();


Resume

Resume may be called when the timer is in PAUSED state. A call to this, like pause above, will throw an IllegalStateException if done in any other state. Resuming will re-register the callbacks & continue the arc animation where it left off. The user may resume by:


    linearTimer.resumeTimer();



Reset

Reset is used to revert LinearTimer to its original state (as it was in the INITIALIZED state). May only be called in PAUSED or INITIALIZED state or IllegalStateException will be thrown. The user may reset the LinearTimer by:



    linearTimer.resetTimer();

Restart

Restart reverts the LinearTimer to its original state and then immediately starts it again. This method is accessible during any state of the timer. Restart can be called by:

    linearTimer.restartTimer();

Timer States

LinearTimer has four states which may be retrieved by linearTimer.getState() method. The states govern the program's flow and when features like start, pause, resume & reset may be accessed. The states are enumerated in LinearTimerStates enum and each has its own integer representation.



State Description Integer representation
1. INITIALIZED The initialized state is when LinearTimer has not run even once and/or .reset() method was executed. Call .startTimer() to move into the active state. 0
2. ACTIVE The active state is when LinearTimer is ticking. From this state, the user may only call .pauseTimer().
 1
3. PAUSED The pause state is when the user has intentionally paused the LinearTimer using the .pauseTimer() method. From this state, only .restartTimer(), .reset() & .resume() may be called. 2
4. FINISHED The Finished state is when LinearTimer has finished ticking and .animationComplete() callback method has been executed. Only .restartTimer() and .reset() may be called.

 3

View Customization

List of attributes available to toggle LinearTimer's look -

Attribute Type Description Methods Default value
1. radius Optional The radius of the circle. setCircleRadiusInDp(int) & getCircleRadiusInDp() 5 dp
2. strokeWidth Optional The thickness of the circle boundary. setStrokeWidthInDp(int) & getStrokeWidthInDp() 2 dp
3. startingPoint Optional The angle from where, in the timer, you want the animation to start. 270 is the 12 O'Clock position. setStartingPoint(int) & getStartingPoint() 270
4. initialColor Optional The initial color of the circle. setInitialColor(int) & getInitialColor() #FFC107
5. progressColor Optional The color of the progress arc that animates over the initial color. setProgressColor(int) & getProgressColor() #00796B

Setting view attributes via XML

xmlns:timer="http://schemas.android.com/apk/res-auto"

<io.github.krtkush.lineartimer.LinearTimerView
     android:id="@+id/linearTimer"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     timer:radius="20dp"
     timer:strokeWidth="2dp"
     timer:startingPoint="270"
     timer:initialColor="@color/colorPrimary"
     timer:progressColor="@color/colorAccent" />

Setting view attributes programmatically

Linear Timer also gives you the option to set the above attributes via java code.

 // Assign attribute values to the view programmatically
 // This will override the attributes set via the XML.

 LinearTimerView linearTimerView = (LinearTimerView) findViewById(R.id.linearTimer);

 linearTimerView.setStrokeWidthInDp(5);
 linearTimerView.setCircleRadiusInDp(40);
 linearTimerView.setStartingPoint(90);
 linearTimerView.setInitialColor(Color.BLACK);
 linearTimerView.setProgressColor(Color.GREEN);

Note that any attributes set via XML will be overridden by the ones declared in the java code.

Builder Methods

Methods that can be used to set certain parameters of LinearTimer while initializing it.

Attribute Type Description Exception
1. linearTimerView() Mandatory Reference to the LinearTimer view. LinearTimerViewMissingException
2. duration() Mandatory Duration for which the timer should run. LinearTimerDurationMissingException
3. timerListener() Optional Receive call backs for various LinearTimer related events. LinearTimerListenerMissingException
4. progressDirection() Optional Direction in which the timer should progress. None
5. preFillAngle() Optional Point till which the progress bar should be pre-filled. None
6. endingAngle() Optional Point till which the progress should fill. None
7. getCountUpdate() Optional Receive updates about the time elapsed since the timer has started or the time remaining for the timer to finish. None

Linear Timer View

linearTimerView() method accepts the view reference to the linearTimerView.

 LinearTimerView linearTimerView = (LinearTimerView) findViewById(R.id.linearTimer);

 ...new LinearTimer.Builder().linearTimerView(linearTimerView).build();

Absence of view reference results in LinearTimerViewMissingException.

Duration

The duration() method is overloaded for the following two cases -

  1. The user provides the total duration and the timer runs for that given duration.
  2. The user provides the total duration and the elapsed time duration. In this case, LinearTimer will automatically calculate the pre-fill angle according to the time elapsed. Also, any value passed into preFillAngle() method will be ignored.

Absence of duration results in LinearTimerDurationMissingException.

new LinearTimer.Builder().duration(10 * 1000).build(); or new LinearTimer.Builder().duration(10 * 1000, 5 * 1000).build();

Timer Listener

A TimerListener can be implemented to receive call backs for various LinearTimer related events.

  1. animationComplete() - When the progress animation comes to an end.
  2. timerTick(long tickUpdateInMillis) - If the user chooses to receive the time elapsed since the timer has started or the time remaining for the timer to finish.

Implement the following interface in your activity -

...implements LinearTimer.TimerListener

Make sure you pass the listener in the LinearTimer builder -

...new LinearTimer.Builder().timerListener(this).build();

And then, override the animationComplete and timerTick methods.

@Override
public void animationComplete() {
  Log.i("Animation", "complete");
}

@Override
public void timerTick(long tickUpdateInMillis) {
    Log.i("Time left or Time elapsed", String.valueOf(tickUpdateInMillis));
}

Absence of correct reference to the listener results in LinearTimerListenerMissingException.

Progress Direction

The user can choose to make the progress bar animate in either clockwise or anti-clockwise manner. To change the direction progressDirection(int progressDirection) method needs to be added while building LinearTimer.

...new LinearTimer.Builder().progressDirection(LinearTimer.COUNTER_CLOCK_WISE_PROGRESSION).build();

progressDirection() can have either of the following two parameters -

  1. LinearTimer.COUNTER_CLOCK_WISE_PROGRESSION
  2. LinearTimer.CLOCK_WISE_PROGRESSION

The default direction is set as clockwise.

Pre-fill Angle

If the user wants to pre-fill the circle with the progress color preFillAngle(float angle) needs to be added while building LinearTimer. The argument contains the angle till which the pre-fill should occur.

...new LinearTimer.Builder().preFillAngle(10).build();

The default value is 0.

Ending Angle

User can change the angle at which the progress ends by adding endingAngle(int endingAngle) method to the Builder.

...new LinearTimer.Builder().endingAngle(360).build();

The default value is 0.

Count Updates

The user can choose to receive the time elapsed since the timer has started or the time remaining for the timer to finish. getCountUpdate(int countType, long updateInterval) needs to be added to the builder along with implementation of TimerListener.

...new LinearTimer.Builder().getCountUpdate(LinearTimer.COUNT_UP_TIMER, 1000).build();

countType can be of the following two types -

  1. LinearTimer.COUNT_UP_TIMER
  2. LinearTimer.COUNT_DOWN_TIMER

updateInterval is the duration after which timerTick() should get an update. This value should always be > 0.