Pull to refresh

Что будет, если у программиста появится хобби кулинария. Часть 2

Level of difficultyEasy
Reading time9 min
Views6.4K
Не только лишь все смогут понять эту шутку
Не только лишь все смогут понять эту шутку

Всем привет, продолжаю свою историю увлечения кулинарией и мобильной разработкой в MIT App Inventor (буду называть "аппинвентор" далее в статье) под это дело. Будет подробно расписана эволюция моего приложения для поиска кулинарных рецептов по составу (это основной базовый функционал) и запредельные, не побоюсь этого слова, возможности аппинвентора, который некоторые считают "инструментом для детей". Кстати, сразу, пока не забыл - дети, если у вас есть интерес к программированию вообще и мобильной разработке под андроид в частности, то я очень рекомендую вам ознакомиться с аппинвентором. А фуллстак-разработчикам и UI/UX дизайнерам возможно будут интересны мои мысли, на основе которых происходила эволюция интерфейса приложения, потому что путь к итоговому результату был очень неблизкий и я бы дорого дал, чтобы сразу придумать то, что получилось в итоге, пропустив промежуточные шаги и сэкономив два года, но я не верю, что это реально в принципе. Зато теперь у меня есть вся эволюция в картинках, так что есть о чем на Хабре рассказать и показать, короче, будет "комикс" ))).

Эволюция интерфейса, этап первый

UI №1 "Зеленый матрас" - кнопки категорий и картинки продуктовUX №1 - тычем на зеленое для открытия/скрытия всех продуктов категории, тычем на картинки для выбора, потом тычем на оранжевое для поиска, красная кнопка с белым крестом снимает выбор
UI №1 "Зеленый матрас" - кнопки категорий и картинки продуктов
UX №1 - тычем на зеленое для открытия/скрытия всех продуктов категории, тычем на картинки для выбора, потом тычем на оранжевое для поиска, красная кнопка с белым крестом снимает выбор
В первых версиях и продукты и рецепты отображались на одном экране
В первых версиях и продукты и рецепты отображались на одном экране
UI №2 - оранжевая кнопка поиска стала лупой, избранные рецепты - звездой, добавил внизу строку поиска по слову в названии, общие картинки категорий появились справаUX №2 - режим исключения запускается длинным нажатием по зеленой кнопке и перекрашивает ее в красный.
UI №2 - оранжевая кнопка поиска стала лупой, избранные рецепты - звездой, добавил внизу строку поиска по слову в названии, общие картинки категорий появились справа
UX №2 - режим исключения запускается длинным нажатием по зеленой кнопке и перекрашивает ее в красный.
UI №3 - Добавлена категория Утварь, Повара добавлены картинками через HorizontalScrollArrangement, черные кнопки рандома для случайного выбора (добавил по-приколу, на самом деле, просто чтобы занять пустое место)UX №3 - Из-за того, что основной экран перегружен, пришлось создать новый экран чисто под вывод рецептов
UI №3 - Добавлена категория Утварь, Повара добавлены картинками через HorizontalScrollArrangement, черные кнопки рандома для случайного выбора (добавил по-приколу, на самом деле, просто чтобы занять пустое место)
UX №3 - Из-за того, что основной экран перегружен, пришлось создать новый экран чисто под вывод рецептов
UX №3 - Экран рецептов и оранжевые кнопки-стрелки моталки по 10 рецептов на экране, без них тут никак
UX №3 - Экран рецептов и оранжевые кнопки-стрелки моталки по 10 рецептов на экране, без них тут никак

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

Экран рецептов изнутри

Этот "(о)город" которого нет (теперь)
Этот "(о)город" которого нет (теперь)

То, что вы видите на картинке сверху это экран рецептов в режиме дизайна и моя головная боль на протяжении почти всей разработки до последнего времени. Объясняю, в чем суть. Динамические интерфейсы в аппинвенторе "из коробки" не поддерживаются, т.е. нельзя на лету создавать кнопки и прочие элементы интерфейса. Поэтому я, как настоящий фанатично упертый трудоголик, ограничил себя статическим интерфейсом с 10-ю рецептами на экране (и мне пришлось внедрить кнопки-моталки, чтобы прокручивать список рецептов на экране). Но это еще не все. Опытным путем выяснилось, что продуктов для каждого рецепта можно воткнуть не более 27, а утвари не более 11. На картинке показано только два шаблона, а ниже их таких еще 8 и при редактировании это все дергается нещадным образом (недоработка аппинвентора, я про это раньше рассказывал). В общем экран рецептов изначально оказался перегружен и никаких 30 (+3) картинок продуктов на рецепт добавить было уже нельзя. Даже 28 нельзя, т.е буквально втыкаешь новую картинку - проект отказывается компилироваться, удаляешь - все норм. Ну и бонусом прочие мелочи, связанные с ожиданием обновления экрана, неудобной прокруткой кнопками-моталками и лимитом в 10 рецептов на экране. Но, скрипя зубами, я поехал с этим экраном рецептов дальше, потому что не видел альтернатив. К слову, посмотрел недавно - для аппинвентора есть сторонние расширения, которые позволяют напихать в него динамический интерфейс, но это страшные костыли, и я их тогда не искал и даже не думал копать в ту сторону. В плане расширений я вообще ретроград и всегда пытаюсь сначала решить проблему имеющимися средствами. Ну ладно, оставляем экран рецептов пока что в покое и переходим к следующему этапу эволюции.

Эволюция интерфейса, этап второй

UI №4 Панель быстрого доступаUX №4 При выборе продуктов они появляются на панели быстрого доступа внизу и из нее чрезвычайно удобно ими управлять
UI №4 Панель быстрого доступа
UX №4 При выборе продуктов они появляются на панели быстрого доступа внизу и из нее чрезвычайно удобно ими управлять

Здесь тут же делаю паузу и рассказываю, как я додумался до этой фичи, потому что считаю ее ключевым и вторым краеугольным камнем вообще всего приложения (первый: продукты-картинками), которая повлияла на всю дальнейшую историю разработки. Итак, до того весь продуктовый выбор отображался непосредственно текстом на кнопках, его приходилось читать, мотать-искать где что написано, потому что на экране все сразу не убиралось даже в свернутых категориях, что уж говорить о развернутых специях и прочих длинных наборах. А почему бы мне выбранные продукты не показывать в отдельной строке снизу? Сказано - сделано, стоп, а если я на них тыркну, то их же можно исключить!!! А зачем тогда мне длинные нажатия на зеленые кнопки, перекрашивания, парсинг текста что включено, а что выключено? И зачем мне тогда вообще весь этот зеленый матрас, только лишь для выбора продуктов? Опа... Ладно, пока идем дальше

Экран рецептов тоже обзавелся панелью быстрого доступа, чтобы никто на забыл, по каким ингредиентам мы ищем, а также я научился таскать с ютуба картинки на превью и подбирать вино к рецептам
Экран рецептов тоже обзавелся панелью быстрого доступа, чтобы никто на забыл, по каким ингредиентам мы ищем, а также я научился таскать с ютуба картинки на превью и подбирать вино к рецептам

Эволюция интерфейса, этап третий. Пользовательские жалобы

То тут, то там (да и теперь до сих пор) стал появляться недовольный народ, который не понимал, что какая картинка обозначает. Кто-то честно признавался, что не помнит флаги стран, кто-то не отличает одну рыбу от другой, кто-то путался в специях, но никто не сказал, что "я мол не знал что за картинка, а потом ткнул на нее и сразу как всё понял", хотя я объяснял всем и каждому, что при тычке на картинках всегда рядом появляется подсказка, что сие такое. Ладно, будет вам текст, первая попытка:

UI №5 Режим "картинка с текстом"UX №5 Дополнительной кнопкой справа вверху можно было включать/выключать режим, где были картинки с текстом
UI №5 Режим "картинка с текстом"
UX №5 Дополнительной кнопкой справа вверху можно было включать/выключать режим, где были картинки с текстом

Опять я, упоротый трудоголик, решил проблему через не то место и огреб на ровном месте кучу новых проблем. Итак, никакого автоформатирования у меня тут не вышло, т.е. красиво скрыть/показать текст рядом со статичными картинками оказалось нельзя. Размер текста меняется, картинки в зависимости от этого пляшут, посему пришлось разруливать через дубликаты, т.е. на каждую категорию два набора кнопок - один с текстом, другой без, и скрыть/показать то один, то другой при смене режима. На все продуктовые категории моего запала не хватило, но я точно помню, что сделал для специй, зелени, мяса, рыбы и сыров. Дальше выяснились три ключевых затыка:

  1. У пользователей на разных телефонах текст все равно обрезается, и то, что на моей трубе выглядит отлично, на другой вообще криво

  2. Удвоение кнопок на главном экране привело к тому, что проект перестал компилироваться

  3. Крепко задумался, что в случае, когда придется прикручивать англоязычность, я очень сильно огребу со всеми этими динамическими лейблами и текстом на них

Короче, режим "картинка с текстом" оказался мертворожденным, но он подвинул меня на изучение и добавление нового элемента интерфейса аппинвентора, а именно ListView, где к тому времени появились новые шаблоны (Image,MainText,DetailText), а до того их не было (Changes between nb186a and nb187 (August 22, 2021)) - где-то год прошел с момента этого апдейта и до времени, когда я сподобился это все прикрутить. У меня на ютуб-канале все этапы разработки запротоколированы, теперь-то стыдно конечно, что я довольно долго пинал свои button/label и тормозил с переходом на вот такую простоту и красоту, но, лучше уж поздно, чем никогда, вторая попытка:

UI №6 ListView вместо кучи кнопок для всех категорийUX №6 Списки можно мотать, можно по ним искать, у всех всё влазит, удобненько
UI №6 ListView вместо кучи кнопок для всех категорий
UX №6 Списки можно мотать, можно по ним искать, у всех всё влазит, удобненько

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

UI №7 "Конец зеленого матраса" Два HorizontalScrollArrangement сверху и два ListView по центруUX №7 Теперь все нормально с выбором, а в правом списке даже влезли сочетающиеся продукты
UI №7 "Конец зеленого матраса" Два HorizontalScrollArrangement сверху и два ListView по центру
UX №7 Теперь все нормально с выбором, а в правом списке даже влезли сочетающиеся продукты

Наконец-то решились абсолютно все проблемы с перегрузом главного экрана, выбором продуктов и динамическим UI. Кнопки ушли вместе с матрасом, приложение значительно облегчилось, также теперь достаточно при добавлении нового продукта просто загрузить картинку в приложение и добавить поле в внешней базе (не надо совать картинку на кнопку, как раньше). И никаких проблем с мультиязычностью в будущем. Кстати, я тут не рассказываю про бэкенд, там тоже подводных камней было немало, но они скучные по большей части и точно не такие интересные, по сравнению с эволюцией фронтенда. Всего лишь раза 4 переделывал базу, мухаха ))). Ну ладно, возвращаясь к интерфейсу главного экрана - когда ничего не выделено, вместо двух списков образуется полным-полно пустого места, что бы туда воткнуть? Ну конечно же 10 случайных рецептов в формате ListView:

Опять рецепты на главном экране, ну что ты будешь делать !
Опять рецепты на главном экране, ну что ты будешь делать !

Стоп, у меня и на главном экране теперь опять рецепты, и старый экран рецептов никуда не делся, дубликат, непорядок, но я же через ListView на главном не сделаю ни кучу картинок продуктов, ни подбор бутылок, ничего, зато можно вывести хоть тыщу рецептов сразу на главный экран моментально, а с другой стороны старый экран рецептов придется все равно рано или поздно убирать, потому что он тормозит и утяжеляет приложение - я к тому моменту понял, что это самое слабое место приложения по всем параметрам - статический интерфейс с 500+ картинок и кучей в принципе лишнего кода, поскольку я уже хоть как вывожу на главный экран рецепты через ListView. Да, и кстати, на этом этапе аппинвентор снова начал отказываться компилировать проект из-за перегрузки опять главного экрана, и мне пришлось, например, вынести из него на другой экран модуль обновления баз и заняться рефакторингом кода, удалением одних картинок тут уже стало не разрулить. Так как же убрать экран рецептов и сделать на главном динамическую загрузку также, как и там, но без тормозов и кнопок перемотки?

Думай

Думай!

Думай!!!

Пока придумывается, расскажу про кое-какие новенькие штучки аппинвентора

В красном квадрате то, что многократно ускорило мои алгоритмы
В красном квадрате то, что многократно ускорило мои алгоритмы

В феврале 2023-го разработчики аппинвентора добавили функционал для работы с листами (Changes between nb191 and nb190a (February 17, 2023) - Add functional list operators like map, filter, reduce, and sort), который многократно ускорил у меня практически всё. Буквально так - был и тормозил цикл с ифами и нету цикла и тормозов. Очень рекомендую внедрять всем, кто ковыряется в аппинвенторе, это must have.

Ну и как тут искать?
Ну и как тут искать?

Выше на картинке часть моего проекта и глаза разбегаются где тут и что. Это самая главная проблема конечно - навигация, никаких "файндов" из коробки не предоставляется кроме двух - можно прыгать по ошибкам и можно перейти на функцию из места, где она вызывается (Highlight Procedure). Но я нашел еще один нетривиальный метод перехода на элемент интерфейса, о котором сейчас вам расскажу, кому-то да пригодится. Все просто до безобразия - нам нужно найти и перейти на событие клика какой-нибудь кнопки, которое мы потеряли в дебрях проекта - находим кнопку и вытаскиваем это событие через левую панель, получаем ошибку, что событие уже определено и прыгаем на эту ошибку, тогда он будет перемещаться между старым событием, где нам нужно что-то поправить и новым пустым - которое мы удалим после исправлений старого. Но инициализацию глобальной переменной таким способом к сожалению не найдешь.

Возвращаясь к моей проблеме динамического списка рецептов на главном экране - самая длинная вертикальная цветная простыня на экране это и есть решение. Сейчас будут подробности. Кульминация все ближе и ближе.

Эволюция интерфейса, этап четвертый. RocknRolla

Внезапно я вспомнил про то, что у аппинвентора есть такой компонент, как WebViewer, который рекомендуется использовать как кастрированный браузер для просмотра страниц в интернете. Я собственно им рецепты-то и открываю, таак, стоп, а только ли в интернете? Локально можно? КОНЕЧНО МОЖНО! Было бы странно, если бы нельзя. А что есть у WebViewer'а, чтобы взаимодействовать с другим функционалом аппинвентора?

Отлично
Отлично

Можно запустить javascript, можно обменяться строкой, все, мне вполне хватит. Итак, план такой - аппинвентором генерим для рецептов html-страницу с css-ом и javascript'ами скармливаем его вьюверу и отображаем его на главном экране аппинвентора, далее через скрипты передаем туда-сюда все, что нам нужно и меняем интерфейс динамически. По итогу у меня там и через innerHTML полным-полно всего меняется, расписывать подробности не буду, потому что это базовый HTML+CSS+Javascript и это самая разжеванная тема везде где только можно, а я ее преподавал (20 лет назад), вспомнил, пригодилось.

Это старая школа, и я в ней директор © Рок-н-рольщик
Это старая школа, и я в ней директор © Рок-н-рольщик
UI №8 "Возвращение матраса" Вверху HorizontalScrollArrangement, по центру WebViewerUX №8 Все без проблем работает через тапы на картинки и подсказки
UI №8 "Возвращение матраса" Вверху HorizontalScrollArrangement, по центру WebViewer
UX №8 Все без проблем работает через тапы на картинки и подсказки

Ну вот и четвертый краеугольный камень приложения - динамический интерфейс по красоте, сколько-угодно картинок, куча самосоздающегося кода на одной html-страничке и никаких проблем с перегрузами. Единственная теперь проблема это автозагрузка превьюшек из ютуба, потому что для сотни рецептов на главном экране это ай-ай-ай. Внимательный читатель спросит меня - а где же третий краеугольный камень приложения? А вон он на картинке, микрофончик справа от дамы видите? Голосовой поиск через внешнее расширение был прикручен в процессе и он отлично взаимодействует с панелью быстрого доступа. Одного без другого точно бы не было, как собственно и всего остального в этой разработке - одно тянется за другим, новый функционал вырастает из старого, старый умирает, как умер первый экран рецептов, хнык. Я же его незамедлительно грохнул после того, как перенес весь функционал в WebViewer. И мне теперь под аналогичный динамический интерфейс и винную карту переделывать, ну это будет дело десятое, сначала мультиязычность и винный погреб, а то я уже забыл где у меня там какие бутылки припрятаны, а надо бы отметить юбилей.

Заканчиваю видеобзором последней на данный момент 10-ой версии и ссылками на скачку, всем спасибо за внимание.

Скачать с гугл-плей

Прямая ссылка (если скачка с гугл-плей недоступна)

p.s. Для создания подобного приложения в одно лицо вам понадобятся (всего лишь):

  1. На фронтенд: MIT App Inventor, HTML, CSS, Javascript, Photoshop

  2. На бэкенд: Google Sheets + App Script + Youtube API

  3. Опыт собственный (много) и куча свободного времени

p.p.s. Раньше я рассматривал App Inventor как средство для создания прототипа приложения, думал что мне от него много не надо, типа накидаю быстро в аппинвенторе основной функционал, а потом, если припрет, перепишу готовое, например на Unity. А теперь думаю - а зачем переписывать?

Tags:
Hubs:
Total votes 6: ↑5 and ↓1+6
Comments36

Articles