Евгений Третьяков

Евгений Третьяков 

Flutter Developer, Full Stack

3subscribers

11posts

goals3
$0 of $1 920 raised
На макбук
$0 of $1 408 raised
Полгода аренды сервера со 128 Гб ОЗУ для реализации проекта собственного узла дешевого бэкэнда для проектов на Dart\Flutter
$0 of $640 raised
Тестирование новых коммерческих сервисов в связке с Flutter (оплата лицензий, абонентской платы и т.п.)

Распаковка проекта и базовые навыки работы с IDE

В своем первом домашнем задании вы получили архив с проектом. Вам его надо будет распаковать и открыть в Android Studio. 
Распаковывать его лучше всего в отдельную папку в корне, как мы раньше говорили, чтобы легче было потом найти файлы - например, c:\app если у вас windows или в папку app в домашней папке пользователя, если у вас Linux или MacOS. Самое главное - не распаковывайте архив на рабочий стол, в папку "загрузки" или "документы"
Дальнейшие инструкции только в самом начале будут для пользователей Windows, сама работа с Android Studio не отличается в разных операционных системах.
1. Распаковываем и открываем папку с проектом
После того, как папка с проектом была скачана и помещена куда надо, нажимаем на нее правой кнопкой мыши и нажимаем на пункт меню "Извлечь все". 
Система спросит путь, если ничего не трогать то распакуется прямо сюда
Еще раз обращаем внимание на путь, куда распаковался проект, чтобы не забыть
После чего открываем Android Stuido. Если вы выполняли предыдущее домашнее задание, то у вас, скорее всего, откроется предыдущий проект. Чтобы открыть новый, нажимаем в меню приложения File -> Open
В открывшемся диалоге находим нашу папку. Если все правильно - она будет отличаться зеленой иконкой. Нажимаем один раз левой кнопкой мыши на эту папку, нажимаем на ОК и у нас откроется проект
Правда, перед тем, как открыться, он спросит - в этом же окне открыть или в новом. Чем больше окон у вас открыто - тем больше расход ресурсов компьютера, поэтому если нет лишней необходимости, то выбираем "в этом окне" - "This window". Галочку "Don't ask again" лучше не ставить.
Проект, который вы открыли, предварительно был очищен от рабочего мусора командой flutter clean для уменьшения размера. Для вас это значит, что первым делом после открытия надо скачать из интернета все зависимости - то есть дополнительные рабочие библиотеки, которые используются в работе.
Система очень недвусмысленно намекнет об этом в всплывающем окне снизу и в виде полосы над окном редактирования кода:
Нажимаем, например, наверху "Get dependencies" - "получить зависимости" - и ждем, пока скачается все необходимое. Обычно это пара минут.
О ходе загрузки IDE будет информировать вас в нижней панели messages - если все закончилось успешно, то последним сообщением будет что процесс закончился с кодом 0. 
Вообще, по древней традиции, самостоятельные небольшие программы, которые работают в составе более крупных систем, возвращают результат своей работы в виде цифрового кода. Код 0 обычно значит, что процесс завершился без ошибок.
Другим косвенным признаком успеха будет то, что строки кода в редакторе перестали быть подчеркнуты красной линией, то есть система больше не считает их ошибочными благодаря скачанным библиотекам.
Следующим шагом надо определиться с устройством, на котором планируется запуск приложения. Если у вас подключен телефон (и он подключен правильно, то есть на нем включены инструменты разработчика и разрешена отладка по USB) - то он будет отображаться среди прочих со своим "понятным" названием, соответствующим модели телефона. 
Если же у вас настроен эмулятор, то он тоже будет в этом списке но немного отдельно, внизу
Если выбрать строку с эмулятором, то он тут же начнет запускаться. Мы для удобства продолжим с эмулятором, хотя использование "реального" телефона в значительной мере облегчит работу системы, если у вас недостаточное количество оперативной памяти - если у вас всего 8 гигабайт или меньше, то запуск на реальном устройстве ощутимо добавит комфорта. При этом в качестве "реального" устройства подойдет любой телефон с версией андроид не ниже 6. Само по себе приложение на Flutter нельзя назвать требовательным, запустится даже если на телефоне всего 1 гиг оперативки.
После того, как определились с устройством, запускаем приложение с помощью кнопки "Run"
Во время первого запуска проекта может показаться, что система зависла, но это не так. Внизу откроется окно с ходом работы, а бегущая полоска справа внизу будет показывать, что процесс идет
После компиляции IDE отправит готовый файл на устройство. 
Внимание! Если вы запускаете на реальном устройстве, то чтобы там запустить новое приложение, придется в явной форме разрешить это. У вас на телефоне появится вот такое сообщение:
Если на него не отреагировать в течение 10 секунд, то установка и запуск не произойдут, а в IDE мы увидим ошибку:
(вообще, любые ошибки подсвечены красным, желтым - предупреждения)
Придется еще раз запустить проект кнопкой Run и на этот раз не пропустить момент появления уведомления на телефоне.
В случае же успешного запуска в окне Run вы увидите много отладочной информации, которая сигнализирует о некоторых моментах выполнения приложения
2. Основы работы с проектом на Flutter
Настало время оглядеться.
Слева вы увидите дерево проекта - оно повторяет структуру папок на диске. Сама программа на Flutter буквально представлена папкой lib и конфигурационным файлом pubspec.yaml. Главный файл, с которого начинается работа - main.dart. Не забудем еще про папку assets, куда мы обычно скидываем файлы, которые должны идти в комплекте с готовой программой - шрифты, картинки, звуки и так далее. 
Если нажать дважды на любой файл - он откроется в основном редакторе. 
Первое, на что надо обратить внимание, прежде чем продолжить - это то, что редактор умеет группировать элементы по общему признаку, либо по коду. За это отвечают маленькие кнопочки левее текста:
Если нажать на них, то он либо сгруппирует, либо "развернет" содержимое. Это используется для того, чтобы легче было сосредоточиться на главном. Давайте развернем группировку:
Обратили внимание, что текст внутри имеет разный цвет?
Например, комментарии в тексте серые. Комментарии выделяются по-разному, я предпочитаю две косых // 
Все, что находится правее после них до конца строки будет считаться комментарием - то есть областью, которая будет игнорироваться компилятором и не пойдет в основную программу. Нам это надо чтобы проще вспомнить, что делает этот код.
Flutter, а точнее язык Dart, который лежит в его основе, очень любит порядок. Этот язык вообще изначально был придуман для описания интерфейсов программ, и если раньше вы уже пробовали свои силы в программировании, то он будет для вас интуитивно знакомым. 
Однако, его любовь к скобочкам разных видов с первого взгляда может напугать. К счастью, IDE всегда подсветит вам вторую (парную) скобку, стоит лишь поставить курсор под скобку:
Вообще, скобки условно делятся на три типа. 
Круглые - в них обычно идет перечисление параметров команды или виджета. Параметры могут иметь название, либо быть безымянными. На примере виджета Text ('какой-то текст', softWrap:true) первый параметр - безымянный, он всегда должен идти впереди, и его нельзя игнорировать. В конкретном случае это выводимый текст. А второй параметр - softWrap - имеет имя, и если мы его не напишем, то система примет решение за нас.
  
Квадратные - в них идет перечисление других элементов одного типа. В 'домашнем' примере вы встретите их неоднократно, постарался подробно их везде описать.
Фигурные - внутри фигурных скобок пишется код, или задаются параметры для структурированных данных (не заморачивайтесь пока насчет незнакомых слов).
Если вам по началу будет тяжело разобраться в том, что и куда пишется - помните, что в случае ошибки вам сразу все подсветят, подчеркнут и подробно напишут, что не так. В крайнем случае всегда можно нажать на отмену (Ctrl-Z) и попробовать снова, по-другому. 
Четкое понимание придет с опытом, на первых этапах достаточно иметь перед глазами эталон с рабочим примером.
Вообще, дружелюбие IDE по отношению к программисту зашкаливает - например, чтобы узнать, какие параметры могут использоваться внутри той или иной функции и какого типа они должны быть, достаточно навести мышку на название функции и вам покажут полный список и немного комментариев, если они есть. 
Например, вот что будет если навести мышь на функцию GetMaterialApp:
Видите? Красной стрелочкой показан параметр, который мы использовали. Их гораздо больше, с ними можно экспериментировать.  Вот пример с более компактной функцией (которая на самом деле виджет):
Каждый параметр имеет свой тип. Знак вопроса после типа обозначает, что он может принимать значение null - то есть отсутствовать и при этом ему не будет назначено никакое значение по умолчанию.
К пониманию, что такое null может приблизить аналогия со стаканом - стакан может содержать что-то, может быть пустым, но оставаться стаканом. Если мы говорим ребенку - "принеси мне стакан воды" - он пойдет на кухню, найдет стакан, и если в нем нет воды - то наберет и принесет. А если стакана нет - то есть он null - то ребенок может либо ничего не сделать, либо взять кружку и наполнить ее. Тут уже все зависит от того, какая программа действий в голове у ребенка - либо выполнить команду во что бы то ни стало, либо "мама, там нет стакана, иди сама". Тут та же история.
Например, в конкретном случае если мы не укажем явно параметр color то программа будет знать, что его нет и он не задан. Как она себя поведет в этом случае? Я предполагаю, что "позовет маму" - отдаст решение вопроса по цвету родительскому виджету.
А если мы явно не укажем параметр clipBehaviour (это то, как он будет работать в случае если содержимое вылезет за границы виджета) то он будет Clip.none, то есть если мы явно не укажем иное, то содержимое будет вылазить за границы виджета.
3. Кстати, что такое виджет?
Во Flutter все отображаемые и неотображаемые экранные элементы называются виджетами. Главная особенность в том, что часть своих параметров отображения виджет наследует от своего родительского элемента - то есть того, который стоит выше.
Вам сейчас не надо вдаваться в подробности, главное понять принцип организации.
Попробуем разобраться на примере виджета, который в приложении показывает шаги приготовления рецепта.
Вот так он выглядит на экране:
Отличительная особенность в том, что это список шагов, количество которых нам заранее (то есть на момент написания программы) неизвестен. Каждый шаг у нас отображается в виде строки из кружочка с номером шага и текстового содержимого, причем текстовое содержимое должно занимать все свободное пространство справа от кружочка с цифрой. 
Вот так выглядит это в коде:
Цифры, конечно, нарисовал я, чтобы облегчить понимание. 
На данном этапе у нас не стоит задачи научить вас программировать, нам сначала надо научиться понимать, что мы видим. 
Итак, перед нами виджет, который лежит в отдельном файле (и который можно использовать потом в любом другом своем проекте). Он для своей работы требует один только параметр - список строк (List<String>), которые он отобразит. Он не лезет ни в какие другие структуры, о чем говорит блок с импортом (import) - там нет ни одной строки, указывающей что ему нужны другие файлы проекта. Это удобный и самостоятельный виджет.
Под цифрой 1 у нас - само тело виджета. Оно начинается со слова @override. 
Под цифрой 2 - со слова reurn начинается уже непосредственный вывод содержимого. Главным виджетом здесь выступает ListView.builder - это такой виджет, который исходя из полученных данных сделает столько виджетов, сколько надо (слово builder намекает). 
Собственно, 3 пункт - как раз и есть та самая строка с шагом приготовления, который мы видим на экране. Там у нас виджет-обертка Container. Обертка (wrap) это такой виджет, который не выводит сам по себе ничего, а используется для того, чтобы организовать вывод дочернего элемента. В частности, он здесь задает симметричный отступ в 8 единиц для своего потомка
Потомок, пункт 4, это тоже обертка. Он обозначает, что внутри мы можем указать некое количество других виджетов (их количество фиксировано! Здесь нет никакого builder), и они будут показаны в строку (row).
Наконец, в п.5 у нас как раз два виджета - кружочек с цифрой и текст.
При этом, порядковый номер (цифра) это текст, обернутый в виджет CirlceAvatar, а текст шага рецепта - обернут тоже в контейнер, который задает отступы по горизонтали, который обернут в виджет Expanded, который сообщает, что это должно занять все пространство на экране, не занятое кружочком....

Как вам такая матрешка? Обертка-обертка-обертка-обертка-текст. 
Это ужасает только на первый взгляд, но если вы вспомните, что Android Studio позволяет группировать и сворачивать такие куски кода - то становится немного легче. Тем более, что сгруппированный кусок можно, не разворачивая, скопировать и вставить куда-нибудь еще. Это ускоряет разработку, но об этом будет на следующем уроке, а использование принципа оберток позволяет лучше понимать происходящее. 
4. Еще пара фишек IDE
Завершая знакомство с редактором кода, хочу показать еще две очень удобные функции.
Во-первых, если вы щелкаете по какому-нибудь слову, то оно подсвечивается на всей странице. Это очень удобно, когда надо понять, где еще используется, например, принимаемый параметр:
Во-вторых, если зажать рукой левую кнопку Ctrl (или Cmd на Mac) и левой кнопкой нажать на какую-нибудь функцию, то нас перекинет в файл, где она была объявлена:Например, в файле main.dart попробуем быстро найти что у нас за страница открывается при старте программы: нажимаем с кнопкой Ctrl на SplashView() - 
- и результат:
Subscription levels3

Внешний вид, интерфейс

$2.56 per month
Коллекции элементов интерфейса, готовые экраны и отдельные элементы

Сниппеты

$6.4 per month
Функциональные блоки кода, решающие определенные задачи. Включает доступ к материалам из подписки "внешний вид, интерфейсы"

Интегрированные экраны

$12.8 per month
Готовые к интеграции экраны с работающей логикой. Включает доступ к материалам из подписки "внешний вид, интерфейсы", "сниппеты"
Go up