14

Разработка приложение "Дневник тренировок"

Здравствуй.

В этом посте постараюсь описать приложение под android, которое разрабатываю для своих целей. Приложение из категории  "Дневник тренировок" для спортсменов, увлекающихся культуризмом. Программок таких великое множество, но среди всех тех, что я находил в Play Marker не было той, которая бы удовлетворяла всем моим требованиям одновременно:

- приятная взгляду;

- нативная;

- бесплатная;

- без рекламы;

- большой каталог упражнений;

- возможность бекапа/восстановления;

- (не обязательно) возможно отправки тренировки другу.


С языка программирования (особенно ООП) я на Вы. Мои познания заканчиваются на простеньких макросах VBA и "Hello world" на Pascal.


Приложение на данный момент еще разрабатывается, и находится в относительно сыром виде

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

Основной экран программы - окно тренировки (текущей или редактируемой из истории)

Левое меню (SlidingMenu) - это история. Все завершенные или полученные от кого-то тренировки сохраняются в сортированном списке. Меню создано при помощи шикарной библиотеки FlipShare.

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

Порядок отображения следующий:

1. Закрепленные (избранные)

2. Полученные от другого пользователя

3. Тренировки которые применялись для повтора

4. Отредактированные

5. Тренировки ранее бывшие закрепленными

6. Новые

В каждой из групп сортировка по дате.

Для каждой записи в истории доступно меню с набором соответствующих функций:

- повторить;

- закрепить/открепить;

- просмотреть;

- редактировать;

- отправить;

- удалить.

Правое меню содержит функции сохранения, восстановления, удаления всей истории. Для кнопок использовал библиотеку Fancybuttons (в данный момент еще в поиске лучшего вида кнопок).

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

А так же функцию регистрации/входа на сайт (в планах) для просмотра статистики (уже более-менее сформирована идея что именно и в каком виде будет там отображаться) и информация об используемых библиотеках (программка увидела мир во многом благодаря разработчикам различных красивых и удобных библиотек, я посчитал что просто обязан разместить информацию о них в своей программе, независимо от того, сколько человек ее увидит)

Основная информация, отображаемая о текущей тренировке это:

1. Название упражнения.

2. Тип упражнения.

3. Общее кол-во подходов в упражнении (не повторений)

4. Общий вес.

В данный момент есть сомнения в полезности некоторой информации из этого списка.

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

Подходы в упражнении можно как отредактировать

Так и удалить.

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

Библиотека ColorDialog.

Верхняя часть экрана тренировки содержит таймер отдыха автоматически запускаемый при добавлении нового подхода. Часики отображаются с помощью библиотеки BetterPickers.

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

При нажатии на таймер отображается окно выбора времени отдыха. Тут я использовал обычные часы, но вместо "ЧЧ:ММ" беру значения как "ММ:СС".

Каталог всех упражнений - это карусель карточек, каждая из которых соответствует своей группе мышц, которые описывает медицинский справочник. Я не стал разбивать на "середина спины", "низ спины" и прочую, на мой скромный взгляд, херн ерунду.

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

По нажатию на маленькую иконку группы мышц открывается список упражнений с описанием (в разработке) и картинками. Библиотека ExpandingCollection. Хоть и выглядит красиво, но работает с лагами, что меня дико бесит.

Просмотр тренировки решил шутки ради сделать в стиле Fallout.

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

Библиотеки Gradientlayout и Markwon.

БД для истории - SQLite. Создал 3 основных таблицы: подходы, упражнений, тренировки. А так же справочная таблица статусов тренировок (полученная, закрепленная,..)

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

Для таблиц создал триггеры обновляющие информацию по общему кол-ву подходов в упражнениях и общему весу в них же.

БД каталога упражнений содержит в себе 7 таблц. 2 из них - то таблицы упражнений и мышечных группы, 1 таблица ссылок в картинкам в папке assets. Таблица типов упражнений:

- базовое;

- изолирующее;

- формирующее.

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

2 остальные таблицы - это текстовые таблицы с описанием и названием упражнений, специфичными для системного языка аппарата.

Одно из самых интересных решений, которые я применил в своем "проекте", и которым хотел бы с вами поделиться (вероятнее всего для многих оно покажется обыденным, но тем не менее я такого примера в интернете, при беглом поиске, не нашел) - это запрос разрешения (для приложения) пользователю в том же контексте, в котором он совершает действие. Пример из моей программы - я хочу отправить тренировку другу, для этого мне нужно сформировать файл на устройстве. Как сделать так, что бы при первичном запуске программы она не просила никаких разрешений, но при нажатии соответствующей кнопки спрашивала о них и при получении положительного результата продолжала выполнять функцию, которую выбрал пользователь. Цепочка - нажал "отправить" - запросило полномочия - отправило. Я это реализовал в связке библиотек MaterialDialogs и Dexter через EventBus. Пользователь нажимает "Отправить", программа проверяет полномочия, если их нет - выдает запрос, и регистрируется на получение уведомлений через EventBus, если пользователь дает полномочия - отправляем соответствующее уведомление и получатель выполняет функцию, которая для этого уведомления предназначена.

Структура проекта, кому интересно:

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

В приложении две активности. Одна для обработки Intent фильтра и получения тренировки (пока что никаких проверок, что именно я получил, не делается. Все сразу пытаюсь преобразовать в строковую переменную и заполнить из нее тренировку). Вторая - основная.

Тренировка, каталог, просмотр тренировки - все это фрагменты отображаемые в контейнере layout основной активности. В activity_main.xml создано 3 FrameLayout. Правила отображения для них свои:

- для текущей тренировки отображаются все 3;

- для редактируемой тренировки верхняя рамка с таймером скрывается (да, он, пока что, продолжает тикать, если пользователь добавит подход)

- для каталога и просмотра тренировки скрываются верхний и нижний контейнеры.


Алгоритм по которому становится известно, кто сейчас в центральном контейнере работает с помощью EventBus. Основная активность замещает фрагмент, в методе onCreateView() фрагмента выдаю уведомление FragmentIsShowed, а в основной активности отрабатываю его. Выглядит примерно так:

Разработка приложение "Дневник тренировок" Приложение на Android, Android разработка, Тренировка, Тренажерный зал, Длиннопост

Из не реализованных функций - "будильник" при окончании времени отдыха. Добавление упражнений в каталог. Сайт с просмотром прогресса (планирую отображать прогресс двумя графиками по всем упражнениям в силовых показателях и выносливости, так как многие спортсмены любят утверждать, дескать 12 раз это на силу, а 13 это уже на выносливость... Что-то ведь надо отображать :) ). Ну и так - по мелочи.


Ну вот, собственно и все.

Зачем этот пост? Просто так. Хотел поделиться своими достижениями (а для меня это достижения, ибо программирование, как я писал выше - для меня новый мир). Программка тут.

Найдены дубликаты

+1

Классное приложение

Иллюстрация к комментарию
раскрыть ветку 1
-4
Красавчик :)
0

Классная программа, можете скинуть исходник?)

0

клёвый пост! автор, держи в курсе )

0
На сегодняшний день есть рабочий вариант?
0

тоже жду приложения, понравилось, ссылочку пожалуйста для скачивания)

0
Комментарий удален. Причина: повторяющийся комментарий или комментарий содержащий информацию рекламного характера.
ещё комментарии
0

Прикольное приложение только не понял зачем библиотека для часов если в сдк такие же часы для версий  > 5

раскрыть ветку 1
-4
Для меня легче возможность кастомизации, а я фанат все покрутить и понастраивать под себя. Еще нахожусь в поиске идеального внешнего вида всех отдельных модулей, часов в том числе.
0
Автор, вы большой молодец
раскрыть ветку 1
-4
Спасибо
0
Как пользователь таких приложений. Редко где описывается как именно нужно правильно делать. Чтобы прям 100% всё тело было описано. И нигде никогда не пишется, какие ошибки можно совершить при выполнении и чем они грозят.
раскрыть ветку 3
-3
Такого же мнения. Это и стало одной из причин решения написать для себя полноценный справочник с функцией дневника.
раскрыть ветку 2
0
Жду вашего приложения👍
раскрыть ветку 1
0
Вылетает
0
Тут я использовал обычные часы, но вместо "ЧЧ:ММ" беру значения как "ММ:СС".

Например, есть значение 23:59. Изначально это 23 часа и 59 минут. А ты записываешь это как как 23 минуты 59 секунд? Или я чего-то не понял? Это, конечно, смекалочка и всё такое, но не укладывается у меня в голове как можно намеренно хранить и использовать неправильные значения. Точнее, значения-то правильные — неправильно интерпретируются.


Фон в галерее мышц не стоит делать таким же как картинки на этом фоне. Тотальный вырвиглаз. Лично я бы не стал там вообще заморачиваться с каруселью, а сделал простые кнопки обычной сеткой в два столбца и вертикальной прокруткой. Больше информации на виду, быстрее выбор.


Плюсанул.

Приложение установилось, но вылетает при запуске. Meizu M3s

раскрыть ветку 1
-4
Да, все верно, значение времени храню именно так. Тут простые соображения - не представляю тренировку, где нужно отдыха аж целвх 23 минуты. Это уже не отдых, а перерыв, тогда есть смысл поставить на паузу и пойти по своим делам или вообще не ставить время отдыха. По поводу неправильных значений - мне кажется, тут таковых нет, в библиотеки нет разницы часы это или минуты, это просто цифра 23 без привязки к какому-то "типу". Мне даже преобразовывать ничего не приходится, кроме, кроме как TimeUnit.MINUTES.toMillis(minutes). А minutes тупо равен числу 23.
0

Много библиотек. Используй нативные возможности ведра:


material-dialogs - android.support.v7.app.AlertDialog

Dexter - requestPermissions (>=Marshmallow)


P.S. понимаю, что для себя, но я не увидел навигацию в toolbar (и его самого кстати тоже), имхо, непонятно, где нахожусь:


setSupportActionBar(toolbar);

setDisplayHomeAsUpEnabled();


P.P.S Не удалось установить. Используй версию сигнатур V1 (Jar) при генерировании apk

Иллюстрация к комментарию
раскрыть ветку 5
-4
Нативные не такие красивые, как к примеру диалоги, либо нужно самому кастомизировать. Не вижу смысла изобретать велосипед. А тулбара никакого и нет. Он тут не нужен. Каталог с просмотром трени и текущей треней не перепутаешь. Всего 3 экрана. Их внешний вид и так говорит о том, где ты находишься, смысла занимать часть экрана тупым дублированием по типу "ты видишь мышечные группы, со списком упражнений - ты в каталоге, но на тебе сверху еще одно подтверждение этому"... Про версии - спасибо, почитаю об этом
раскрыть ветку 4
0

Смысл не в дублировании, а в навигационной составляющей. На некоторых устройствах могут как присутствовать (так и отсутствовать) наэкранные клавиши (домой, меню, назад), это минус в использовании. Можете чекать этот момент, и показывать один из типов меню.


Тоже самое касается и планшетов. На 10' мне проще нажать на Toolbar, чем вертеть планшет в руках.


А диалоги давно умеют в custom layout, надо не ленится (и загружать Dalvik 65K methods limit либами)


Повторюсь: если для себя - пожалуйста. Если кому то поюзать - велосипед уже придумали.


Успехов =)

раскрыть ветку 1
0
Насчёт изобретения велосипеда стоит сказать, что много библиотек тоже не есть хорошо - они как никак к весу прибавляют иногда неплохо так. Да и к тому же, если прям совсем переусердствовать, можно в 40к лемит упереться. А случае с диалогами, имхо, проще написать быстро класс отвечающий за кастомизацию, чем искать либу/читать ее доки и потом тащить все ее исходники ради пары использований(если вы конечно не используете ProGuard, хотя там тоже иногда морока та ещё бывает).
раскрыть ветку 1
0
В форме "подход/вес" добавь кнопки с предустановленными значениями для веса и данного вида снарядов для подхода. Вопрос как это разместить. И списки можно сделать настраиваемыми или адаптирующимися. Чтобы на самую частую операцию тратилось меньше всего времени
раскрыть ветку 1
-4
Плохо понял о чем ты, можешь разжевать для "одаренных"?
-4

Комментарий для тех, кто, возможно, сюда заглянет.

Сторонние библиотеки, писали ранее - лучше использовать как можно меньше. Основной аргумент был в избыточном кол-ве методов и пагубном влиянии на итоговый размер приложения. Сейчас общий "вес" - 13.5 MB. Из них 8.5 MB приходится на папку assets, где, на данный момент лежат не обработанные, еще пока, фотографии для каталога упражнений. Папка res, где находится большое кол-во иконок в высоком разрешении (которые в релизной версии планируется заменить на более низкого качества не в ущерб внешнему виду, но в пользу уменьшения размера приложения) - 2.3 MB суммарно. Оставшееся место ~3MB приходится на полезную часть программы. Не знаю, на сколько это критично, но до озвученного предела в 40 мб для плей маркета еще явно далеко.

Но проблема проявилась в другом - приложение перестало запускаться при первичной установке (я тестировал запуск из AS и было все OK). Оказалось использование большого кол-ва одинаковых зависимостей стало причиной возникновения ошибки с описанием как "Unable to instantiate application android.support.multidex.MultiDexApplication". Решение я выбрал как самое простое для себя это - добавление в конфиг Gradle следующей строчки "multiDexEnabled true". Но правильным вариантом будет исключить в конфиге все избыточные зависимости из сторонних бибилотек, а вот это уже влечет за собой реальную кучу гемора...

Похожие посты
Похожие посты закончились. Возможно, вас заинтересуют другие посты по тегам: