Designing a Custom Progress bar with timed breaks in Android

Sarina Dhamija
OLX Engineering
Published in
6 min readFeb 15, 2021

--

Introduction

Have you ever come across a special requirement of customizing the progress bar by introducing breaks in its progress. If yes, then you are at the right place. In this post, we will draw a circular progress bar with breaks which can be used as a video recording button in which breaks are an indicator of paused time of the video.

Before we start

Let’s understand the requirement for the video recording button.

All the images shown above are different states of the recorder button.

i. Initial state

ii. Paused state

iii. Resumed state with pause break

  • Initially, the button will be shown by the outer circle.
  • Now when the user clicks on this button, the recording starts, and the arc will show the progress of recording based on time, and as the video is paused, progress will stop.
  • After this when the video recording is resumed the paused time will be shown by a small arc drawn in a different color which represents a break in the video recording. The Colour of the circles in the progress bar can be customized.

This post is divided into the following sections

  1. Rendering UI: Here we will understand the initial requirements of the progress button
  2. Progress Bar State Logic: This part will cover different states maintained by the button to show progress and breaks
  3. Drawing Phase: Then finally we will cover how this button is drawn based on different recorder states.

Getting Started

Now as we know the requirement, let’s see how we can paint this image.

Rendering the UI

  • Attribute set: The color of the circles are customizable. They are added to the attribute set and can be added during the initialization of the button with other attributes.

The variables defined in XML are retrieved while initialization of class which is then added to paint object of the circles and arc.

  • Value Animator: This property animation is used to handle the expansion of the inner circle and progress of the outer circle.

In this inner circle, the size will be used as animated values to handle animation of the inner circle, and the duration of the video being recorded is used as the animated value to show outer border circle animation as a progress bar.

  • Interpolator: This defines the rate of change of an animation. This allows basic animation effects to be accelerated, decelerated, repeated, etc
  1. AccelerateDecelerateInterpolator: This interpolator helps in the transition of the outer circle to track the progress of recording.
  2. LinearInterpolator: This interpolator helps in the transition of the inner circle when the recording starts.
  • Paint: This class is used to draw circles and arcs with different colors and styles. To show breaks in progress, the Paint object will be set with a different color.

Each time the progress arc is drawn, the color of the Paint object, along with sweep angle and start angle, is changed to show paused state and resumed state. In this project Color.WHITE is used to show progress and Color.TRANSPARENT is used to show breaks in the progress bar.

Progress Bar State Logic

  • Recorder states: The RecorderStateManager manages four states of video recording :
  1. INIT
  2. RESUMED
  3. RECORDING
  4. PAUSED

When a user clicks on the recorder button then based on the current state different actions are performed.

For example,

  • If the current state of the button is INIT, this means the button is just initialized and on click, the recording will start. In this case, onClickStart() method will be called which is responsible for tasks like saving resume time or pause time, start value animator, reset values when video recording is ended, etc and the current state value of the button will be changed to RECORDING.
  • As the animation changes, the arcs will be drawn as per the start state. Similarly, if the current state is PAUSED state then onClickResume() will be called and the state of the button will be changed to a RESUMED state in which resume time will be saved and outer border animation value will also change.
  • Actions: The callback to the events of the recorder button will be handled at view using IRecorderActions. The view can override these methods to handle camera-related actions for example onStartRecord() can be used to start video recording in-camera.

Drawing Phase

In this phase as the animation starts the circles and arcs are drawn based on new animated value and the current state of the recorder. Let’s see what the onDraw() method will do as per the current state of RecorderStateManager.

  • Init: If the current state of the recorder button is INIT state then the only inner and outer circle will be drawn as the recording is not started yet.
  • Start: If the current state of the recorder button is START then along with the inner and outer circle the arc for recording progress needs to be shown which depends on the current time and the maximum time allowed for recording.
  • Pause: In the paused state, the color of the arc can be changed as per the users' requirements. For the time being this is kept as white. Based on a sweep and start angle a separate arc will be drawn to mark paused time of the video.
  • Resume: As the video is resumed the start angle of the arc change based on the last paused time and the sweep angle will be calculated using the current time.

Now that we know what should be drawn in different recording states, let's do some math to draw arcs to represent resumed and paused state

In the above diagrams

  • S: Start Time
  • P1, P2: Paused Time
  • R1, R2: Resume Time
  • x, y: Sweep Angle for arc

The sweep angle for the pause break is always 10f and the sweep angle for the arc while recording a video will be calculated using the following method.

Based on user action, all the times will be stored. Whenever a user pauses a video that time is recorded and stored in the pauseTimeList. Similarly when recording is resumed the time is stored in a resumeTimeList. All the arcs will be drawn based on the times stored in the list.

In the onDraw method of view, we need to draw an arc as per the current recording state of the button. For every state first step will be to draw an inner and outer circle. The arcs will be drawn as mentioned below:

  1. Started State :
  • draw an arc for started state

2. Paused State: In this state pauseTimeList and resumeTimeList will be used to draw an arc and the following two steps will be implemented for all the time saved in the list. For both steps sweep angle and start angle will e calculated based on paused time and previous resume time.

  • draw an arc for resumed state
  • draw arc for paused state

3. Resumed state: In this step also different pauseTimeList and resumeTimeList will be used to draw an arc in the same manner as done in the paused state but in this case, when all the arcs are drawn based on both the lists then a final arc for the resumed state will be drawn that will show recording and its sweep angle will be calculated based on the current time.

Final Words

This customizable progress bar is a reusable component and can contribute in multiple use cases like video recording, uploading, etc. The implementation for video recording has already been discussed in this post.

Future Scope: The future scope for this project includes the introduction of a template for the button in which this video recording button can be further customized with attributes like shape, size, etc. We can introduce different icons in the center of the button to represent paused, resumed, and stopped state to make this more interactive.

The complete code for this project can be found in this link.

--

--