Routine Tracker is a planner that aims to simplify managing activities that you need to perform consistently. It combines features of a planner calendar app and a habit tracker allowing you to keep all your activities in one place.
The motivation for this project is simple. I couldn't find any planner or habit tracker that estimates how long it will take you to achieve a goal based on your progress. So I decided to build it myself. I aim to develop a universal solution for planning and tracking your projects as well as scheduling your daily tasks and events.
- Flexible schedules. The app supports daily, weekly, monthly, and alternate-day schedules. You're free to choose specific days or inform the app how many times you wish to complete the task within a period.
- Adaptive schedule that changes automatically based on your progress. When you fail to complete your routine, you’ll be suggested to sort out the backlog on the next non-due day. And vice versa, when you over-complete your routine, the next scheduled occurrence will be canceled. This behavior can be altered in the settings.
- Adequate streaks. Streaks do not only form out of multiple completions in a row. Non-due days are included in the streak as well. Your streak will remain unbroken as long as you complete the habit the planned number of times within a given period.
- Plan ahead. The routine calendar displays completions, streaks, and planning dates to help you visualize your progress and plan your future time effectively. View a clean and organized agenda for any date, eliminating visual clutter.
- Modern UI. Enjoy a visually appealing and modern interface, following the principles of the Material You design. The application supports both light and dark modes, landscape orientation, and dynamic color on Android versions 12 and later.
- Completely free app with no limitations. Track as many habits as you wish. Routine Tracker is entirely free and contains no ads or in-app purchases.
- Works offline and respects your privacy. Routine Tracker operates independently without needing an internet connection or online account registration. Your confidential data always remains on your device. Neither the developers nor any third parties can access your information.
- edit routine and routine description
- completion time and reminders
- reordering the routines in a draggable list
- skip days and put your routines on vacation
- simple tasks
- measurable routine
- Automatic completion date estimation
- Routine by a list of tasks that repeats on every period. E.g. upper body workout, ab workout, and leg workout → repeats every week.
- Routine by a comprehensive list of tasks that are necessary for achieving your goal.
You can install the app from the GitHub releases page (make sure to turn off installing from Unknown sources in your Android device settings beforehand) or build it yourself by cloning the project and launching it in the latest version of Android Studio.
You're welcome to share your thoughts, suggest features, and ask questions in GitHub discussions!
The app is built with modern Android technologies and is designed to follow the best practices.
It utilizes:
- Jetpack Compose for the user interface, with a single Activity and no Fragments
- Official Compose navigation library
- View model for business logic separation
- SQLDelight database for local data storage
- Kotlin coroutines and flow for asynchronous requests
- Koin for dependency injection
- JUnit 5 for unit testing
- kotlinx-datetime for working with dates
- A super convenient Calendar library for Android. (shoutout to @kizitonwose)
The app follows:
- MVVM pattern
- CLEAN architecture with both repository and use cases
- SOLID principles
- multi-module architecture as suggested in the NowInAndroid modularization learning journey. It involves convention plugins and version catalogs for managing dependencies across modules.
I embrace the possibility of utilizing Kotlin Multiplatform for porting the app to other platforms in the future, so SQLDelight, Koin, and Kotlinx-datetime are used instead of traditional Android libraries such as Hilt, Room, and java.time.
-
ScheduleIsDue.kt
contains an extension function that determines whether an activity is due or not. This is the simple part. It’s thoroughly tested in theScheduleIsDueTest.kt
However, since we also need to account for the habit’s progress, a more complicated logic is required. This is whereHabitStatusComputerImpl.kt
comes into play. This class is responsible for computing one of theHabitStatus
es, which is in the end displayed to the user. This functionality is thoroughly tested in theHabitStatusComputerImplTest.kt
. -
Heavy form validation and sharing data between screens in the
add_routine
feature module. -
Collapsing toolbar in Jetpack Compose built as suggested here:
CollapsingToolbarLarge.kt
-
Feature modules do not access the repository directly, everything is done through use cases. But at the same time, we avoid boilerplate by making use of Kotlin functional interfaces. 😎 Example:
HabitDomainModule.kt
-
State for handling one-time events, no SharedFlows and Channels involved. After each observation of the event, the state is reset back to its default value. This is unified with the help of extensions in
UiEvent.kt
Rationale:- state can't be lost in any scenario (read more);
- easy to use not only in
ViewModel
s, but also in plain state holder classes; - ensures immediate response to new events (such as when a snackbar needs to be updated immediately upon a new event, instead of waiting for the previous message to disappear).
Name | Responsibility |
---|---|
app |
Serves as an entry point of the app and brings everything together |
build-logic |
Contains convention plugins that reduce the gradle boilerplate for declaring dependencies in the modules |
core:data |
Contains repository classes that serve as a single source of truth for accessing data from the offline database and data that comes from the network. Although Routine Tracker doesn’t fetch data from the network yet, this layer is implemented to follow the best practices. |
core:database |
On-device local database |
core:domain |
The heart of the app, which contains logic for determining whether the habit is due or not, computing streaks, etc. It operates on data that comes from the data layer. |
core:logic |
Utilities and helper classes written in raw Kotlin and not dependent on Android SDK. |
core:model |
Kotlin data classes and enums used throughout the app for abstraction |
core:testcommon |
Common testing logic and fake classes that are used in tests throughout the app. |
core:ui |
Jetpack Compose components, theming logic, and helpers for Android. |
feature |
User interface with View Models, functionality associated with a specific feature or user journey. |
The app currently stands at the MVP stage. Without your help, I won't be able to implement all the planned features. So, if you're inclined to offer support in any of the following areas:
- Development for the Android version,
- Porting to iOS or web platforms,
- Design enhancements,
- Translation to different languages,
- Promotion, and spreading the word about the app
- Identifying and reporting bugs,
- Or any other contributions you might have in mind,
and are willing to do so voluntarily, please don't hesitate to open an issue, submit a PR, or reach out to me directly.
Whether you're a seasoned developer or just looking to hone your skills, your contributions are much appreciated.
Please note, as per the GitHub Terms of Service, any code contributions will be licensed under the GPL v3, as it is the license of the original project.
The project is licensed under the GPL, which means that you can freely build on top of it for commercial and non-commercial purposes alike. But should you choose to incorporate its code, you must open-source your project and apply the GPL license to it as well. Check out the LICENSE file for more details.