Як Android-розробник тайм-менеджментом захопився, і що з цього вийшло

Привіт, Хабр. Хочу вам зізнатися. Я — Ледар. Ця темна таємниця, ретельно ховається від оточуючих. Тому, цур нікому ні слова.
Щоб ніхто з оточуючих не здогадався про це, доводиться постійно працювати. Але частенько під час роботи, відволікаюся на всякі сторонні речі. Новини почитати, подивитися пошту, історію повідомлень. В результаті, відволікаючі заняття, займають дуже багато часу, і страждає імідж. Іноді, я близький до викриття.
Але одного разу я знайшов методику управління своїм робочим часом, під назвою «Pomodoro». І написав додаток «Таймер Трудової Людини». Тому, що я — Android-Розробник!


Отже, нижче під катом я розповім про творчих метаннях, головоломаниях, та інших сопуствующих творчого процесу принади.

Частина перша (задумлива)
Коротко про систему «Pomodoro». Все наше робочий час розділимо на певні періоди роботи і відпочинку, звані «Помідор» (назва пішла від форми кухонного таймера, яким користувався винахідник методу Франческо Чирилло). Загальноприйнято співвідношення 25 хвилин на роботу і 5 на відпочинок.
Основна ідея полягає в тому, що робочий час (25 хвилин) ви працюєте/вчіться по-справжньому, не відволікаючись ні на що (ось зовсім-зовсім ні на що). Потім 5 хвилин ви робите що хочете (в рамках КК і суспільної моралі).
Перед початком роботи, ви складаєте список скільки «помідорів» ви хочете витратити на кожну задачу. Наприклад: підготовка до іспиту — 3 штуки, вивчення нового матеріалу — 4 і т. д.
Зі свого досвіду, можу сказати, що ця методика дуже ефективна (природно, що не став би я радити, не випробувавши на собі).
Винахідник методики використовував кухонний таймер у вигляді помідора, звідки, власне, і пішла назва. Але використовувати його в офісі, і лякати колег дивним тиканьем і несподіваними дзвіночками — не комільфо. Тому раніше я використовував секундомір на телефоні, і блокнот. Але це теж виявилося не зручно.

В Android Market, дуже багато таймерів працюють з томатною техніці. Мені ж хотілося чогось свого, теплого, і лампового, без додаткових функцій (за висловом мого колишнього начальника — «Свистілки, перделки і фантики»), без реклами та інших сумнівних принад. Плюс, я сам хотів налаштовувати свої власні часові проміжки.

Так і що вже там, я хотів написати своє власне додаток, як у дорослих.

Частина друга (експериментальна)
Перша версія виглядала просто і примітивно. Таймер, кнопка, меню налаштування. Початковий стан:


В процесі роботи:


У меню параметри можна вибрати кольори шкали, і тривалість етапів роботи/відпочинку.


Таймер отрисовывался на Canvas.
Але позбувшись від таймера, я не пішов від листочків з розкладом. Тому вирішив зробити повну перебудову.

Частина третя (перестроечная)
Отже, в оригінальній системі тайм-менеджменту «Pomodoro», основна ідея полягає в тому, що ви заздалегідь плануєте скільки часу у вас піде на ту чи іншу задачу. Тому, вирішив додати список завдань. Але людям вже сподобалася можливість роботи в режимі «нон-стоп». Тому старий функціонал повинен був вижити. Ось так тепер виглядає зараз головне меню:


Для тих, хто хоче працювати із звичайним таймером, без заморочок з розкладом – я залишив класичну версію, доступну по кнопці «Працювати без списку завдань» (на початковому екрані). Відразу обираєте час роботи/відпочинку і працюєте, як у першій версії.


Також під ніж пішла можливість вибирати кольори для шкали часу. Замість цього було створено кілька гармонійних колірних схем, і можливість вибирати одну з них. Зі схемами у мене був дикий танець з бубнами, благополучно вирішене (про це дивіться нижче).


Отже, якщо ви хочете створити новий розклад завдань на день, то натиснувши на кнопку «Створити/завантажити список завдань», ви можете розпланувати свій робочий день.
Кнопка «Додати робочий цикл» — додає завдання, розбиту на декілька етапів. Причому кожен етап включає в себе час для роботи, і невеликої перерви.


Через кожні чотири «помідора», рекомендується влаштовувати велику перерву на півгодини-годину. Тому була додана кнопка«Додати перерву».


Створивши свій список завдань, ви можете підкоригувати його і зберегти.


Так ви можете створити собі кілька розкладів, відразу на тиждень.


Довге натискання на пункт списку дозволяє або відредагувати список завдань, або почати з ним працювати. Робочий екран виглядає так:


Почавши працювати зі списком, вгорі ви бачите назва поточного етапу, його номер і кількість етапів на дану задачу. Трохи нижче список всіх циклів (в дужках вказані час роботи і відпочинку). Основне місце займає головний таймер, як з першої версії програми. Якщо ви впорались із завданням достроково, то можете натиснути на кнопку «Завершити завдання достроково», і тим самим видалити її зі списку. У разі, якщо ви не вклалися в розклад, то кнопка «Додати цикл», додасть ще один цикл завдання.

Частина четверта (околотехническая)
Одним з головоломних моментів, для мене, було створити єдині колірні схеми для застосування. Все хотілося зробити в стилі Material. Але при тестуванні на різних пристроях полізли косяки. Те, що виглядало пристойно на версії Android 5.x, на 4.x версії виглядало жахливо.

Врешті-решт я прийшов до такого рішення. Створив набори Material-кольорів:

Файл colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#64B5F6</color>
<color name="colorPrimaryDark">#2196F3</color>
<color name="colorAccent">#0D47A1</color>

<color name="colorPrimaryTeal">#4DB6AC</color>
<color name="colorPrimaryDarkTeal">#009688</color>
<color name="colorAccentTeal">#004D40</color>

<color name="colorPrimaryGreen">#8BC34A</color>
<color name="colorPrimaryDarkGreen">#689F38</color>
<color name="colorAccentGreen">#33691E</color>

<color name="colorPrimaryRed">#e57373</color>
<color name="colorPrimaryDarkRed">#f44336</color>
<color name="colorAccentRed">#b71c1c</color>

<color name="colorPrimaryOrange">#FF5722</color>
<color name="colorPrimaryDarkOrange">#E64A19</color>
<color name="colorAccentOrange">#BF360C</color>

<color name="colorPrimaryAmber">#FFD54F</color>
<color name="colorPrimaryDarkAmber">#FFC107</color>
<color name="colorAccentAmber">#FF6F00</color>

<color name="colorPrimaryAutumn">#FF5722</color>
<color name="colorPrimaryDarkAutumn">#4CAF50</color>
<color name="colorAccentAutumn">#E64A19</color>

<color name="colorPrimaryIndigo">#7986CB</color>
<color name="colorPrimaryDarkIndigo">#3F51B5</color>
<color name="colorAccentIndigo">#1A237E</color>

<color name="colorPrimaryBlack">#9E9E9E</color>
<color name="colorPrimaryDarkBlack">#616161</color>
<color name="colorAccentBlack">#212121</color>

<color name="colorText">#ffffff</color>
<color name="colorTextHint">#c8ffffff</color>

</resources>


І файл зі стилями:

Файл styles.xml
<resources>
<style name="MyDialogStyle" parent="Theme.AppCompat.Dialog.Alert">
<item name="android:windowFrame">@null</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsFloating">true</item>
<item name="android:textSize">30sp</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowTitleStyle">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:background">@android:color/transparent</item>
</style>

<style name="BlueButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape</item>
</style>

<style name="GreenButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape_green</item>
</style>

<style name="TealButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape_teal</item>
</style>

<style name="AmberButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape_amber</item>
</style>

<style name="BlackButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape_black</item>
</style>

<style name="IndigoButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape_indigo</item>
</style>

<style name="LightBlueButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape_autumn</item>
</style>

<style name="OrangeButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape_orange</item>
</style>

<style name="RedButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:background">@drawable/button_shape_red</item>
</style>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowBackground">@color/colorPrimaryDark</item>
<item name="android:itemBackground">@color/colorPrimaryDark</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/BlueButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>

</style>

<style name="AppTheme.Launcher">
<item name="android:windowBackground">@color/colorPrimaryDarkBlack</item>
</style>


<style name="TealTheme" parent="AppTheme">
<item name="colorPrimary">@color/colorPrimaryTeal</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkTeal</item>
<item name="colorAccent">@color/colorAccentTeal</item>
<item name="android:windowBackground">@color/colorPrimaryDarkTeal</item>
<item name="android:itemBackground">@color/colorPrimaryDarkTeal</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/TealButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>
</style>

<style name="GreenTheme" parent="AppTheme">
<item name="colorPrimary">@color/colorPrimaryGreen</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkGreen</item>
<item name="colorAccent">@color/colorAccentGreen</item>
<item name="android:windowBackground">@color/colorPrimaryDarkGreen</item>
<item name="android:itemBackground">@color/colorPrimaryDarkGreen</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/GreenButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>
</style>

<style name="AmberTheme" parent="AppTheme">
<item name="colorPrimary">@color/colorPrimaryAmber</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkAmber</item>
<item name="colorAccent">@color/colorAccentAmber</item>
<item name="android:windowBackground">@color/colorPrimaryDarkAmber</item>
<item name="android:itemBackground">@color/colorPrimaryDarkAmber</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/AmberButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>
</style>

<style name="BlackTheme" parent="AppTheme">
<item name="colorPrimary">@color/colorPrimaryBlack</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkBlack</item>
<item name="colorAccent">@color/colorAccentBlack</item>
<item name="android:windowBackground">@color/colorPrimaryDarkBlack</item>
<item name="android:itemBackground">@color/colorPrimaryDarkBlack</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/BlackButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>
</style>

<style name="IndigoTheme" parent="AppTheme">
<item name="colorPrimary">@color/colorPrimaryIndigo</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkIndigo</item>
<item name="colorAccent">@color/colorAccentIndigo</item>
<item name="android:windowBackground">@color/colorPrimaryDarkIndigo</item>
<item name="android:itemBackground">@color/colorPrimaryDarkIndigo</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/IndigoButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>
</style>

<style name="AutumnTheme" parent="AppTheme">
<item name="colorPrimary">@color/colorPrimaryAutumn</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkAutumn</item>
<item name="colorAccent">@color/colorAccentAutumn</item>
<item name="android:windowBackground">@color/colorPrimaryDarkAutumn</item>
<item name="android:itemBackground">@color/colorPrimaryDarkAutumn</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/LightBlueButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>
</style>

<style name="OrangeTheme" parent="AppTheme">
<item name="colorPrimary">@color/colorPrimaryOrange</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkOrange</item>
<item name="colorAccent">@color/colorAccentOrange</item>
<item name="android:windowBackground">@color/colorPrimaryDarkOrange</item>
<item name="android:itemBackground">@color/colorPrimaryDarkOrange</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/OrangeButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>
</style>

<style name="RedTheme" parent="AppTheme">
<item name="colorPrimary">@color/colorPrimaryRed</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkRed</item>
<item name="colorAccent">@color/colorAccentRed</item>
<item name="android:windowBackground">@color/colorPrimaryDarkRed</item>
<item name="android:itemBackground">@color/colorPrimaryDarkRed</item>
<item name="android:itemTextAppearance">@android:style/TextAppearance.Large</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textColorHint">@color/colorTextHint</item>
<item name="buttonStyle">@style/RedButtonStyle</item>
<item name="dialogTheme">@style/MyDialogStyle</item>
<item name="alertDialogTheme">@style/MyDialogStyle</item>
</style>
</resources>


І для кожної схеми довелося створити свою форму для кнопки. Наприклад, для схеми «Індіго»:

Файл button_shape_indigo.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="15dp"/>
<solid
android:color="@color/colorPrimaryIndigo"/>
<stroke
android:width="2dp"
android:color="@color/colorPrimaryDarkIndigo"/>
<padding
android:left="40dp"
android:right="40dp"
android:bottom="10dp"
android:top="10dp"/>
</shape>


У фрагменті налаштувань задавалося ім'я схеми, і при старті будь активності (в onCreate) відпрацьовував такий код:

Функція вибору теми
public static void setNewTheme(Context mContext){
SharedPreferences sp;
sp = PreferenceManager.getDefaultSharedPreferences(mContext);
String colorScheme = sp.getString("colorScheme у", "blue");
if(colorScheme.equals("blue"))
mContext.setTheme(R. style.AppTheme);
else if (colorScheme.equals("green"))
mContext.setTheme(R. style.GreenTheme);
else if (colorScheme.equals("teal"))
mContext.setTheme(R. style.TealTheme);
else if (colorScheme.equals("amber"))
mContext.setTheme(R. style.AmberTheme);
else if (colorScheme.equals("black"))
mContext.setTheme(R. style.BlackTheme);
else if (colorScheme.equals("indigo"))
mContext.setTheme(R. style.IndigoTheme);
else if (colorScheme.equals("autumn"))
mContext.setTheme(R. style.AutumnTheme);
else if (colorScheme.equals("orange"))
mContext.setTheme(R. style.OrangeTheme);
else if (colorScheme.equals("red"))
mContext.setTheme(R. style.RedTheme);
}


Частина п'ята (околорекламная й трохи скандальна)
Додаток спочатку писав для себе. І тому робити будь-які вкладення в рекламну кампанію, не бачив сенсу. На всяк випадок, перевів додаток на англійську. І посидівши у векторному редакторі, хвилин за 15 сваял іконку і головну картинку (та, що вгорі посту). Розмістив додаток на 4pda. Там у сумі вийшло близько 150 скачувань.

Також, я пишу історії зі свого життя на Пикабу. Людям подобається, є передплатники. Тому розмістив два поста (про першої і другої версії відповідно, послідовно по мірі виходу версій). Але на жаль, парочка тролів, вирішили «пожартувати», і нацькували модератора зі скаргою, що «мовляв реклама програми, і заборонено правилами». Модератор не розібравшись тему про першу версію видалив, і дав бан на два тижні. Але, лист на підтримку, вирішило цю проблему, і адміни розблокували статтю. Правда троль не заспокоївся, і вимагав «Забаньте його за неграмотний Російську мову і пунктуацію! », але нахапавши мінусів благополучно злився. Другий пост, про нову версію тролити вже не намагалися. Загалом, аудиторія прийняла додаток прихильно, вказали на кілька помилок (виправлені).

Ось власне і вся моя історія написання програми. Природно, додаток доступно безкоштовно і без реклами. Ніякої матеріальної вигоди, крім морального задоволення (і трохи, для задоволення манії величі), і бажання поділитися корисним інструментом з спільнотою, автор не отримує.
Отже дозвольте відкланятися. Сподіваюся комусь це буде корисним. Якщо у когось є зауваження або підказки, з великим задоволенням їх вислухаю.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.