This is a full-featured Stopwatch application built using pure Dart and Flutter. I wanted to create a reliable utility that handles accurate timing, lap analysis, and background operation without needing any external packages.
Watch this short video to see the app in action, showing the core timing, lap recording, how the lap analysis modes work, and the dark/light theme toggle.
rishab-ms-stopwatch-assignment-recording.1.mp4
The app is built to be totally reliable—you won't lose time if you minimize it.
- The Engine: It uses the standard
dart:async'sStopwatchfor the core time tracking, which is highly accurate. - Handling Minimizing: The app listens for when it's moved to the background (paused) and when it comes back (resumed) using
WidgetsBindingObserver. When minimized, the timer that updates the UI is stopped to save battery, but the underlying DartStopwatchkeeps ticking perfectly. When you return, the time display immediately jumps to the correct, elapsed time. - Smooth Display: We use
Timer.periodicto update the UI very frequently (e.g., every 30 milliseconds), making the time display look smooth.
The list of recorded laps offers clear, useful feedback.
- Configurable Views: You can switch between display modes:
- Highlight: Automatically colors the fastest lap (Green) and the slowest lap (Red) so you can quickly see your extremes.
- Percentage Change: Shows you how much faster (down arrow) or slower (up arrow) the current lap was compared to the one right before it.
I kept the state management simple and clean, as no external packages were allowed.
- Built-in State: All data—the current time, all lap records, and settings—is handled inside the main Widget using only the native
setState()method. - Theming: The app supports both light and dark modes, which you can switch via a settings option.
- Stable Digits: The main clock uses a special font feature (
FontFeature.tabularFigures()) to ensure all numbers have the same width. This prevents the time from "jumping" side-to-side as the numbers change. - Tactile Feel: Buttons use
HapticFeedbackfor a light vibration when pressed, giving it a more native app feel. - Clean Transitions: The Start/Stop button uses an
AnimatedSwitcherto change its text and color smoothly.
The entire logic and interface live in one main file for ease of use.
. ├── lib/ │ ├── app_theme.dart # Where the light and dark themes are defined. │ ├── main.dart # The app entry point, handles the theme state. │ └── stopwatch_screen.dart # The main file. Contains all logic, state, and UI. └── README.md
- Clone this repository:
git clone [Your Repository URL]
- Go into the project folder:
cd [Project Name] - Run the application on an emulator or connected device:
flutter run