Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. React Native
Code

Начинаем работу с раскладками React Native

by
Difficulty:BeginnerLength:LongLanguages:

Russian (Pусский) translation by Natalia Dushkina (you can also view the original English article)

В этом уроке вы научитесь верстать приложения на React Native, и узнаете, как сверстать часто используемые в приложениях раскладки страниц. Это такие раскладки, как stack-раскладка, grid-раскладка и absolute-раскладка. Я предполагаю, что вы знакомы с основами написания стилей для приложения на React Native, и в целом с тем, как писать CSS стили, поэтому не буду сильно заострять внимание на Stylesheet.create и на том, как добавлять стили разным элементам.  

Исходный код для этого урока вы можете найти на Github.

Развёртывание проекта

Чтобы упростить работу, воспользуемся React Native for Web. C React Native for Web Starter, мы сможем легко запустить новый проект на React Native, который будет работать и в браузере. Этот код 100% совместим с React Native project. Для каждой раскладки страницы мы создадим отдельный компонент, который по желанию можно будет потом импортировать в обычный проект на React Native. Мы будем использовать React Native for Web для того, чтобы было легче настроить и запустить проект.

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

После того, как закончится установка, перейдите в директорию app/components. Там лежат файлы, с которыми мы в основном будем работать.

Откройте файл App.js и замените код по умолчанию на следующий код:

Впоследствии, сюда вы можете импортировать компоненты, которые мы будем создавать далее, и отрисовывать их на странице с помощью этого файла. Просто запомните, что любой компонент, который мы сохраним в папке layouts, не должен отрисовываться никаким другим файлом. Например, для файла layouts/StackLayout.js добавьте в App.js:

Запустить проект можно следующей командой:

Тогда запущенный проект будет доступен в браузере по адресу http://localhost:3000. Если вы измените любой из файлов, импортированных в App.js, то произойдёт полная перезагрузка страницы.

Как верстать разные раскладки страниц

Раскладки страниц в React Native верстаются с помощью подмножества спецификации флексбокс. (Я говорю «подмножество», потому что используются не все положения из спецификации). Так что если вы уже знакомы с флексбоксом, то можете применять свои навыки в React Native. Ещё стоит отметить, что в React Native нет плавающих блоков и процентных значений. Так что верстать можно только с помощью флексбокса и CSS позиционирования.

Stack-раскладка

Первая раскладка, которую мы сверстаем, это stack-раскладка. В случае вертикальной ориентации, элементы выкладываются один под другим, а в случае горизонтальной — следуют друг за другом. Давайте сначала рассмотрим случай вертикальной ориентации:

Vertical Stack Layout

Ниже код этой раскладки:

Из кода выше ясно, что сначала мы получаем доступную приложению высоту окна. Затем вычисляем высоту каждого блока. Так как у нас три блока, то делим доступную высоту на три.

В вёрстке должен быть контейнер, оборачивающий все эти блоки. Общие стили задаются в объекте box, а уникальные цвета фона  — в объектах с уникальными названиями (box1, box2, box3).

При использовании флексбокса контейнеру нужно добавить свойство flex. Значение этого свойства влияет на то, сколько пространства займет блок. Если оно равно 1, это означает, что он займёт всё доступное пространство, при условии, что у него нет соседей. Позже мы рассмотрим пример использования свойства flex в случае, когда у блока есть соседи.

flexDirection позволяет задать главную ось раскладки. По умолчанию это column. Для flexDirection, равного column, дочерние элементы контейнера будут выкладываться вертикально (друг под другом), а для row — горизонтально (друг за другом). Для того, чтобы высота блоков была одинаковой, задайте высоту box равной вычисленному ранее значению.

Вот рисунок, который помогает понять, как контент будет распределяться по странице в зависимости от значения flexDirection.

Illustration of flexDirection row and column

Только что я вам продемонстрировал фиксированную вёрстку.  Вы не сможете использовать Dimensions для вычисления ширины или высоты элементов, если ваше приложение поддерживает как портретный, так и ландшафтный режимы ориентации устройства. Потому что как только пользователь повернёт устройство, ширина или высота, которую вы вычислили до этого, станут неправильными.  React Native не станет их автоматически пересчитывать, так что приложение будет странно выглядеть.

Флексбокс сможет сделать вычисления за вас, нужно только указать правильные значения. Для того, чтобы добиться такой раскладки, как в примере выше, без использования Dimensions, всё, что вам нужно сделать, это указать flex: 1 для всех блоков вместо указания конкретного значения height.

Теперь рассмотрим пример использования flex в случае, когда у блока есть соседи. Пусть есть 3 соседних блока с одним и тем же значением flex. Так как значение flex у всех одинаковое, то все три блока поровну разделят между собой доступное пространство. (Вообще в этом случае любое значение flex даст тот же эффект, если оно будет одинаковым у всех этих блоков).

С помощью этих знаний вы теперь сможете верстать раскладки с шапкой, основным контентом и подвалом:

Вот как будет выглядеть результат:

Stack Layout header content footer

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

Горизонтальные stack-раскладки

Для того, чтобы сверстать горизонтальные stack-раскладки, всё, что вам нужно сделать, это изменить значение flexDirection на row.

Если поменяем значение свойства flex у блоков обратно на 1, то получится такая раскладка:

Мы поменяли только свойство flexDirection, которое теперь равно row.  Так как у всех блоков flex: 1, то они будут одинаковой ширины и высоты. Все идеи вертикальной stack-раскладки применимы и в этом случае.

Выравнивание контента

Если хотите проконтролировать то, как распределятся дочерние элементы внутри контейнера, установите свойство justifyContent для контейнера. 

Ниже пять возможных значений этого свойства. В примерах ниже высота каждого дочернего элемента уменьшена для наглядности. Вы бы не увидели никакой разницы, если у каждого дочернего элемента свойство flex было бы равно 1, потому что в итоге они заняли бы всё доступное пространство

  • flex-start: дочерние элементы прижаты к началу. Обратите внимание на белый фон прямо под последним дочерним элементом. Вот как вы понимаете, что используется flex-start, потому что все дочерние элементы сдвинуты к началу. Из-за этого в конце осталось пустое пространство.
Flex Start
  • flex-end: дочерние элементы прижаты к концу. Отметим, что в этом случае пустое пространство осталось в начале.
  • center: дочерние элементы выровнены по центру контейнера. В этом случае пустое пространство делится поровну между началом и концом контейнера.
Flex Center
  • space-around: дочерние элементы распределены так, что между ними появились одинаковые отступы.  Это означает, что у внешних элементов осталось меньше пространства на их внешних сторонах, а отступы между каждыми двумя соседними элементами удвоились.
Flex Space Around
  • space-between: дочерние элементы распределены так, что между ними появились отступы одинакового размера.
Flex Space Between

Как вы могли заметить, каждое из этих стилевых свойств зависит от высоты или ширины дочерних элементов. Оно зависит от ширины, если flexDirection равно row, или от высоты, если flexDirection равно column.

Например, space-between никак не повлияет на вертикальную stack-раскладку, если каждый дочерний элемент использует свойство flex для контроля высоты.  Это потому, что не останется никакого свободного пространства на отступы между дочерними элементами.

Выравнивание элементов

На первый взгляд justifyContent и alignItems как будто делают одну и ту же вещь. У них также совпадают три возможных значения: flex-start, flex-end и center, помимо этого у  align-items есть свойство stretch.

Основное различие между justifyContent и alignItems заключается в том, по какой оси будут выравниваться дочерние элементы. Как вы уже знаете, justifyContent всегда выравнивает дочерние элементы по главной оси. А alignItems — по поперечной оси, которая перпендикулярна главной.

Мы уже знаем, что то, какая ось будет главной, а какая — поперечной, зависит от значения свойства flexDirection. Так что, если flexDirection равно row, основная ось идёт слева направо. Значит, поперечная ось идёт сверху вниз. С другой стороны, если flexDirection равно column, тогда поперечная ось идёт слева направо.

Ниже приведено несколько примеров, в которых попарно сравниваются результаты применения justifyContent и alignItems, при условии, что flexDirection равно row. В каждом примере сначала показан результат применения justifyContent, а за ним — результат применения alignItems.

  • flex-start: элементы позиционируются одинаково, поэтому результат применения alignItems выглядит точно так же, как и justifyContent.
justifyContent and alignItems flex-start
  • flex-end: теперь мы начинаем видеть разницу. В первом случае, блоки сдвинуты к концу первого ряда, а во втором случае — к началу последнего ряда.
justifyContent and alignItems flex-end
  • center: в случае center блоки располагаются по тем же принципам, как и в других рассмотренных выше случаях. В первом случае блоки центрированы по оси x, а во втором — по оси y.

justifyContent and alignItems center

  • stretch: используйте это значение, если хотите, чтобы дочерние элементы растянулись и полностью заполнили контейнер. Это значение по умолчанию свойства alignItems, так что явно указывать его необязательно. Вы уже видели, как оно работает, когда мы верстали вертикальную и горизонтальную stack-раскладки.

Вот код для рассмотренных выше примеров. Просто поиграйте со значениями свойств flexDirection, justifyContent и alignItems, если хотите понять, как они влияют на раскладку:

Если хотите дополнительно выровнять отдельные дочерние элементы контейнера, то можете использовать свойство alignSelf. Все возможные значения свойства align-items также применимы и к этому свойству. Так, например, вы можете выровнять отдельный элемент так, что он будет прижат к правому краю контейнера, в то время как остальные будут прижаты к левому краю.

Grid-раскладка

С React Native на самом деле не поставляется никакой системы grid-раскладки, но флексбокс — достаточно гибкая вещь, которая позволяет нам такую систему создать самим.  Используя полученные знания, мы можем воспроизвести grid-раскладки с помощью флексбокса. Вот пример:

Grid Layout

А вот код этой раскладки:

Из вышеприведённого кода ясно, что мы эмулируем то, что обычно происходит внутри CSS грид-фреймворков. Каждый ряд обёрнут в отдельный view, а элементы сетки — внутри него. Каждому элементу по умолчанию присвоено flex, равное 1, так что доступное пространство ряда поровну распределяется между всеми элементами. Тем элементам, которым нужно больше пространства, устанавливается более высокое значение flex. Ширина остальных элементов автоматически пересчитывается, и все элементы располагаются так, как следует.

Если хотите создать отступы между элементами в ряду, то добавьте padding каждому из них, а затем внутри каждого добавьте блок. 

Получится такая раскладка:

Grid Layout With Spaces

Absolute-раскладка

React Native поддерживает только absolute и relative позиционирование. Правда, это не должно вас ограничивать, потому что вы всегда можете скомбинировать такое позиционирование с флексбоксом и добиться желаемого результата.

Давайте посмотрим на то, как сверстать следующую раскладку:


Мы легко бы её сверстали, если бы у нас были все те возможности для позиционирования блоков, которые имеются в десктопном браузере. Но, так как у нас React Native, то сначала нужно подумать, что можно сделать с помощью флексбокса, а уж позиционировать маленькие блоки с помощью CSS.

С использованием флексбокса такая раскладка может быть свёрстана двумя способами. Свойству flexDirection основного контейнера можно присвоить как значение row, так и column. Дальше всё зависит от того, какой способ вы выберете. Мы присвоим flexDirection значение row, так что экран будет поделен на три колонки. В первой колонке будет оранжевый блок, во второй — чёрный, серый и зелёный блоки, а в третью колонку попадут голубые блоки и маленький фиолетовый блок.

Если вы уже знаете, как именно нужно раскладывать каждый элемент, нужно просто применить знания, полученные в этом уроке. В конце концов, на самом деле нам не нужно позиционировать с помощью CSS большие блоки, нужно проделать это только с маленькими блоками.

В первой колонке только оранжевый блок, так что, применив к контейнеру justifyContent: 'center', получим желаемый результат. На всякий случай напомню, что значение по умолчанию свойства flexDirection это column. Это означает, что если вы установите justifyContent равным center, то дочерние элементы будут центрированы по оси Y.

Ко второй колонке применимы все те же идеи, только в этот раз мы не хотим центрировать все блоки по вертикали. Мы хотим, чтобы между ними были равные отступы, и justifyContent: ‘space-between’ помогает нам этого добиться. В то же время мы ещё хотим выровнять все дочерние элементы по оси X, так что используем alignItems: ‘center’.

Единственная хитрость тут заключается в том, что вы не должны задавать ширину серому блоку, потому что мы хотим чтобы он растянулся на всю ширину контейнера. Так как мы не задавали никакой width, мы должны применить alignSelf: stretch к серому блоку, чтобы он растянулся на всю ширину своего родителя.

Далее, для того, чтобы немного сместить маленький красный блок относительно его первоначальной позиции, нужно использовать position: relative и задать значения top и left, потому что относительная позиция отсчитывается от верхнего левого угла его родителя.

Что касается маленького оранжевого блока, мы используем position: 'absolute' потому, что нам нужно выровнять его относительно верхнего правого угла его родителя. Это сработает, потому что абсолютно спозиционированные элементы в React Native привязаны к своему родителю.

Для вёрстки третьей колонки применимы все те же идеи, так что не буду на них останавливаться.

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

Для того, чтобы сделать это, нужно использовать компонент ScrollView, так что если основной контент перестанет помещаться в контейнер, React Native автоматически сгенерирует вертикальную полосу прокрутки. Это позволяет нам добавить marginTop и marginBottom контейнеру основного контента, так что фиксированные шапка и подвал не поломают вёрстку основного контента. Также отметим, что left и right у шапки и подвала установлены в 0, так что они займут всю ширину экрана.

Вот как это будет выглядеть:

Fixed header and footer

Сторонние библиотеки

У React Native большое интернет-сообщество, так что не удивительно, что уже существует несколько библиотек, облегчающих вёрстку раскладок. В этом разделе я расскажу вам о библиотеке React Native Easy Grid. Вы можете использовать её для того чтобы верстать раскладки страниц приложения с помощью компонентов Grid, Row и Col.

Установить её можно с помощью следующей команды:

Импортируйте нужные вам компоненты библиотеки в ваш файл.

Компонент Grid это блок-обёртка, внутри которого все находится. Col используется для создания колонок, а Row — для создания рядов. Вы можете задать свойство size одновременно и для Row, и для Col, хотя ниже мы задали его только для Row. Если свойство size не задано, то доступное пространство будет поровну разделено между всеми объектами Col.

В данном случае колонок всего две, так что экран делится на две колонки. Первая колонка затем делится на два ряда. Здесь мы задали свойство size, но вы можете не задавать его, если вам нужны 2 ряда одинакового размера, как ниже.

После этого, остается только добавить стилей рядам и колонкам:

Как вы могли заметить, у React Native Easy Grid весьма интуитивное API.

Заключение

В этом уроке вы узнали, как верстать раскладки страниц для приложений на React Native. В частности, вы узнали, как использовать подмножество стандарта флексбокс для React Native, для того, чтобы позиционировать разные вещи. Ещё вы узнали, как использовать React Native Easy Grid, она облегчает вёрстку флексбоксом. 

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

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.