Как я сделал своё Android-приложение для списков дел на Jetpack Compose — и опубликовал его в RuStore

Как я сделал своё Android-приложение для списков дел на Jetpack Compose — и опубликовал его в RuStore

Привет! Меня зовут Даниэль, и сегодня я хочу рассказать как я создал своё Android-приложение TuDu — простой и удобный планировщик задач без рекламы и регистрации. Расскажу с чего всё началось, что я изменил, с какими проблемами столкнулся и как в итоге опубликовал приложение в RuStore.

С чего всё началось

Идея появилась просто — мне не нравились существующие приложения для списков дел. Одни перегружены функциями, другие требуют регистрацию, третьи завалены рекламой. Я хотел что-то чистое, быстрое и работающее без интернета.

Писать приложение с нуля было бы долго и сложно. Поэтому я нашёл отличный открытый проект — Compose-ToDo от разработчика wisnukurniawan на GitHub. Это полноценное приложение на Jetpack Compose с хорошей архитектурой: Room для базы данных, Hilt для dependency injection, DataStore для настроек, MVVM паттерн. Отличная основа!

Я решил сделать рескин — взять этот проект, полностью переработать дизайн, добавить свои функции и опубликовать под именем TuDu.

Что представляет из себя TuDu

TuDu — это приложение для управления задачами с трёхуровневой структурой:

  • Группы — папки для списков. Например «Работа», «Дом», «Личное»
  • Списки — коллекции задач с названием и цветом. Например «Покупки», «Ремонт»
  • Задачи — конкретные дела с датой, временем, напоминанием, шагами и заметкой

Приложение работает полностью офлайн. Никакой регистрации, никакой рекламы, никакой облачной синхронизации — просто открыл и работаешь.

Что я изменил и добавил

Работа над проектом заняла немало времени. Вот что я сделал:

1. Переименование пакета

Первым делом переименовал пакет с com.wisnu.kurniawan.composetodolist на com.tudu.android.mylist. Казалось бы простая задача, но на практике это оказалось настоящим испытанием.

При переименовании через Android Studio часть файлов осталась в старых папках, часть переехала в новые — получились дублирующиеся структуры. Пришлось вручную копировать файлы через проводник Windows и делать массовую замену через Ctrl+Shift+R. После этого ещё долго боролся с ошибками компиляции — Room не мог найти сгенерированные DAO классы, пока не очистил кэш и не пересобрал проект.

2. Новое нижнее меню навигации

Оригинальное приложение имело боковое меню (drawer). Я полностью заменил его на нижнюю навигацию с пятью вкладками:

  • Главная — основной экран со списками
  • Календарь — просмотр задач по дням
  • + — центральная кнопка добавления (FAB)
  • Списки — вкладка только со списками без карточек статистики
  • Настройки — открывает экран настроек

Кнопка «+» открывает BottomSheet с выбором — «Новый список» или «Новая группа».

3. Новый дизайн главного экрана

Полностью переработал главный экран. Добавил:

  • Приветствие по времени суток — «Доброе утро ☀», «Добрый день 👋», «Добрый вечер 🌆», «Доброй ночи 🌙»
  • Строку поиска прямо на главном экране
  • Горизонтальный календарь-карусель — прокручиваемая полоса с днями, текущий день выделен цветом
  • Фильтры-таблетки — «Сегодня», «Планирование», «Все» — для быстрой фильтрации задач
  • Кнопку «Поддержать» — ведёт на страницу доната

Убрал старые карточки статистики «Сегодня», «Запланированные», «Все» которые занимали много места.

4. Экран календаря

Добавил новый экран с визуальным календарём на основе стандартных Android компонентов. Календарь показывает текущий месяц, дни с задачами отмечены точкой. При нажатии на день отображается список задач этого дня.

5. Русская локализация

Добавил полный русский перевод. Переименовал папку values-in (индонезийский) в values-ru. Перевёл все строки интерфейса на русский язык.

6. 24-часовой формат времени

Оригинальное приложение использовало 12-часовой формат (AM/PM). Это оказалось неожиданно сложной задачей — MaterialTimePicker игнорировал системные настройки формата времени.

В итоге заменил MaterialTimePicker на стандартный TimePickerDialog с параметром is24HourView = true — это гарантирует 24-часовой формат независимо от настроек устройства.

7. Удаление списков свайпом

Добавил возможность удалять списки свайпом вправо — как уже работало для задач. Для этого пришлось добавить:

  • Метод deleteList в интерфейс IListDetailEnvironment
  • Реализацию в ListDetailEnvironment
  • Action Delete в ListDetailAction
  • Обработчик в ListDetailViewModel

8. Настройка ProGuard для release сборки

Это была самая неприятная часть. Debug версия работала отлично, а release падала при выборе языка или темы. Ошибка в логах была:

java.lang.RuntimeException: Field theme_ for m5.n not found

Оказалось что ProGuard переименовывал поля Protobuf классов которые DataStore ищет через reflection. Решение — добавить правила для сохранения полей:

-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite { <fields>; } -keep class * extends com.google.protobuf.GeneratedMessageLite { *; }

9. Иконка и название

Создал новую иконку приложения и переименовал его в TuDu. Заменил иконки во всех папках mipmap для разных плотностей экрана (mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi).

Технический стек

Приложение написано на Kotlin с использованием современного Android стека:

  • Jetpack Compose — декларативный UI
  • Room — локальная база данных
  • Hilt — dependency injection
  • DataStore + Protobuf — хранение настроек
  • Coroutines + Flow — асинхронная работа
  • Navigation Compose — навигация между экранами
  • MVVM — архитектурный паттерн

С какими проблемами я столкнулся

Переименование пакета — самая болезненная операция. Android Studio не всегда корректно переносит все файлы. Несколько раз проект переставал собираться из-за того что часть файлов осталась со старым пакетом.

ProGuard в release сборке — потратил много времени на поиск причины краша. Debug версия работала идеально, release падала. Оказалось что нужны специальные правила для Protobuf.

MaterialTimePicker и AM/PM — казалось бы мелочь, но CLOCK_24H параметр не работал на некоторых устройствах. Пришлось полностью заменить компонент.

Git и первый push — при попытке загрузить проект на Gitverse получил ошибку non-fast-forward потому что репозиторий уже содержал файлы (README, .gitignore). Решилось через --force флаг.

Публикация в RuStore

После сборки release APK загрузил приложение в RuStore. Процесс публикации достаточно простой — нужно заполнить описание, загрузить скриншоты и иконку, дождаться модерации.

Приложение уже доступно для скачивания: 👉 https://www.rustore.ru/catalog/app/com.tudu.android.mylist

Что планирую добавить

  • Виджет на рабочий стол
  • Экспорт и импорт данных
  • Статистика выполненных задач
  • Больше языков интерфейса

Открытый исходный код

Весь исходный код проекта открыт. Можете смотреть, форкать, предлагать улучшения:

Если хотите поддержать развитие проекта — есть кнопка доната прямо в приложении, либо напрямую через YooMoney: 👉 https://yoomoney.ru/fundraise/1GV365N919A.260405

Буду рад любым отзывам, предложениям и звёздочкам на GitHub! Если у вас есть вопросы по разработке — спрашивайте в комментариях.

Начать дискуссию