Подробный обзор виджета GridView
Класс GridView описывается как прокручиваемый двумерный массив виджетов и предлагает до пяти конструкторов для создания такого массива. На странице Класс GridView вы найдете простой пример отображения макета сетки, состоящего из двух столбцов. В каждом столбце по три ряда стихов из бродвейского мюзикла Гамильтон.
Подобно виджетам CustomScrollView и ListView родительским классом GridView является класс ScrollView. ScrollView - это, по сути, виджет, который может прокручивать свое содержимое. Ниже приведен рисунок, изображающий задействованную иерархию классов. Многие из названных параметров и свойств, переданных в виджет GridView при создании, полностью возвращаются к использованию его родительским классом ScrollView.
Постройте свою сетку
Опять же, есть пять конструкторов, из которых можно выбрать, когда дело доходит до создания виджета GridView. В этой статье мы рассмотрим, что каждый конструктор предоставляет пользователю, а также быстро опишем назначение множества именованных параметров, предоставляемых в каждом из них. На снимке экрана ниже вы можете увидеть, например, что четыре названных конструктора совместно используют первые одиннадцать параметров исходного генеративного конструктора GridView (), но затем имеют разные набор параметров для других конкретных целей.
Только скриншоты. Щелкните для Gists.
Как всегда, я предпочитаю использовать скриншоты, а не суть, чтобы показать код в своих статьях. Я считаю, что с ними легче работать и легче читать. Однако вы можете щелкнуть / коснуться их, чтобы увидеть код в сущности или в Github. По иронии судьбы, эту статью о мобильной разработке лучше читать на компьютере, чем на телефоне. Кроме того, мы программируем в основном на наших компьютерах; не на наших телефонах. Теперь.
Нет движущихся изображений Нет социальных сетей
Обратите внимание, что в этой статье будут файлы gif, демонстрирующие аспекты рассматриваемой темы. Однако сказано, что просмотр таких файлов gif невозможен при чтении этой статьи на таких платформах, как Instagram, Facebook и т. Д. Помните об этом и, возможно, прочтите эту статью на medium.com.
Давай начнем.
Подсчитайте сетку
В примере в документации используется один из наиболее распространенных вариантов виджета GridView: GridView.count. Он создает макет сетки с фиксированным количеством дочерних виджетов, перечисленных вдоль его поперечной оси. Обратите внимание: когда дело доходит до макетов сетки, основная ось совпадает с направлением прокрутки (обычно вертикально вверх и вниз), а горизонтальное направление определяет поперечную ось.
Итак, именованный параметр, crossAxisCount, в данном случае имеет целочисленное значение 2, что дает макету сетки два столбца. Дочерние элементы (список виджетов) разнесены друг с другом с помощью свойств crossAxisSpacing и mainAxisSpacing - обоим назначено «логическое количество пикселей», равное 10. Ниже приведен снимок экрана кода, составляющего этот пример GridView, а также краткий список с описанием остальные именованные параметры, используемые для его определения.
bool primary
- Если true, то «Контроллер прокрутки» неявно получается фреймворком.
final EdgeInsetsGeometry padding;
- Размер пространства вокруг всего списка виджетов.
final double crossAxisSpacing;
- Количество логических пикселей между каждым дочерним элементом, указанным вдоль креста axis.
final double mainAxisSpacing;
- количество логических пикселей между каждым дочерним элементом, указанным вдоль главной оси.
Ваше основное поведение
Значение по умолчанию для параметра primary - true. Вы можете обратиться к предыдущей статье Декодирование ListView для получения дополнительной информации об этом параметре и его связи с Контроллером прокрутки. В конце концов, виджет ListView и GridView имеют общий родительский класс, ScrollView.
Файлы gif, работающие ниже, демонстрируют, если мы «закомментируем» основной параметр, для которого установлено значение false, при этом будет выбрано значение по умолчанию true. Это приводит к тому, что при прокрутке отображается «свечение индикации перескроллинга», обычно наблюдаемое в данном случае на телефонах Android. Казалось бы, поскольку в простом примере все «дочерние виджеты» отображались на одном экране, не было необходимости в прокрутке, и поэтому для основного параметра было установлено значение false.
Удалить некоторые отступы
Как вы видите на скриншотах ниже, быстро становится очевидным, что происходит, если в простом примере закомментировать именованный параметр, padding. Маленькие зеленые прямоугольники окружали «границу» примерно из 20 логических пикселей. Обратите внимание: «Логические пиксели» - это примерно одинаковый визуальный размер на разных устройствах, а «Физические пиксели» - это размер фактических аппаратных пикселей на устройстве. Как видите, логические пиксели - это средство быть независимым от устройства.
Без интервала
Пространство между маленькими зелеными блоками в простом примере обеспечивается именованными параметрами, crossAxisSpacing, и mainAxisSpacing. Как видите, простое удаление этих параметров приведет к удалению промежутков между зелеными блоками, которые составляют список виджетов в GridView.
По горизонтали
Как указывалось ранее, по умолчанию «Направление прокрутки» для виджетов GridView - вертикальное. Однако установка его в горизонтальном направлении теперь позволит прокручивать в примере, но это "вперед и назад", как вы можете видеть из файла gif, показанного ниже.
Поместите это в обратном направлении
Это довольно очевидно на простом примере того, что произойдет, если вы установите для именованного параметра reverse значение true. Как вы видите ниже, список виджетов просто указан в «противоположном» направлении вдоль главной оси. По умолчанию, конечно же, установлено значение false.
Физика прокрутки
Следующий параметр, который мы рассмотрим, называется физика. Он определяет, как будет вести себя прокручиваемый список, когда пользователь достигнет начала или конца прокрутки, и как он будет вести себя, когда пользователь отпустит, и прокрутка будет продолжаться некоторое время. Он принимает объект класса типа ScrollPhysics. В нашем простом примере недостаточно для прокрутки, поэтому я обратился к примеру с поваренной книгой Работа с длинными списками, снова используя виджет ListView для демонстрации поведения прокрутки.
В настоящее время существует четыре подкласса класса ScrollPhysics - три из них показаны ниже. Первый имитирует поведение, наблюдаемое в Apple iPhone, BouncingScrollPhysics. Второй класс, ClampingScrollPhysics, дает свечение индикации чрезмерной прокрутки, обычно наблюдаемое на телефонах Android. Последний продемонстрированный метод называется NeverScrollableScrollPhysics, полностью отключающий возможность прокрутки. Не отображается AlwaysScrollableScrollPhysics. Он обеспечивает соответствующее поведение в зависимости от платформы: Android или iOS.
Заверните
Еще раз обратимся к примеру ListView, чтобы понять, что происходит, когда для свойства shrinkWrap установлено значение true, а не остается значение по умолчанию false. Легко понять, что происходит при использовании жирной красной границы.
В документации сказано: «Если вид прокрутки не сжимается, то вид прокрутки расширяется до максимально допустимого размера в [scrollDirection]». - В приведенном выше примере это вертикальное направление. Если вы установите для свойства shrinkWrap значение true, как мы сделали выше, прокручиваемый список (или представление с прокруткой) обернет свое содержимое и будет настолько большим, насколько это позволяют дочерние виджеты.
В документации также отмечается снижение производительности, если для этого свойства установлено значение true: «Сжатая упаковка содержимого представления прокрутки значительно дороже, чем расширение до максимально допустимого размера, потому что содержимое может расширяться и сжиматься во время прокрутки, что означает размер прокрутки необходимо пересчитывать при изменении положения прокрутки ».
Еще немного
Мы продолжим просматривать список именованных параметров и описывать их использование, но сделаем это, представив четыре конструктора, которые можно использовать для создания виджета GridView.
Учиться на примере
Теперь мы реализуем тот же простой пример с остальными конструкторами, предлагаемыми классом GridView. Это подчеркнет сходство и, более того, различия между этими пятью конструкторами.
Делегируйте свою сетку
Исходный генерирующий конструктор GridView () требует, чтобы объект класса явно передавался его именованному параметру gridDelegate. Он предназначен для управления компоновкой дочерних элементов в GridView и расширяет класс SliverGridDelegate.
Конструкторы GridView, GridView.builder и GridView.custom явно требуют передачи такого делегата сетки в указанный параметр, gridDelegate. В то время как другие конструкторы, GridView.count и GridViewe.extent, создают за вас такой объект класса. Например, класс SliverGridDelegateWithFixedCrossAxisCount назначается конструктору GridView.count и создает макет с фиксированным количеством виджетов вдоль поперечной оси. Класс SliverGridDelegateWithMaxCrossAxisExtent создает макет виджетов вдоль поперечной оси с учетом максимальной протяженности пространства вдоль этой оси и назначается конструктору GridView.extent . Ниже приведен снимок экрана конструктора GridView.count. Вы можете видеть, что для этого создаются делегаты.
Примеры простого примера
Теперь посмотрим, как можно использовать другие конструкторы для получения тех же результатов в отношении простого примера. Вы можете видеть ниже (отображается слева), «делегат сетки» GridView принимает свойства crossAxisSpacing и mainAxisSpacing, которые участвуют в размещении виджетов. Он также принимает "счетчик по осям", поэтому вы видите целое число 2. Наконец, он принимает явный список уже определенных виджетов, которые будут отображаться в GridView.
Если внимательно присмотреться к реализации GridView.builder справа, она тоже должна назначить «делегат сетки». Логично использовать тот же самый, что и GridView. Однако вы можете видеть, что вместо этого используется именованный параметр с именем itemCount, а оператор switch-case используется для отображения определенных виджетов в зависимости от значения индекса. Вы можете сказать, что это не самая эффективная логика для такого простого примера. Это потому, что этот конструктор больше подходит для сеток с большим (или бесконечным) количеством отображаемых виджетов. Фактически, виджеты, которые еще не определены, но вместо этого определяются на лету! Как видите, подпрограмма «itemBuilder» этого конструктора (см. Ниже) вызывается только для определения тех виджетов, которые должны быть видны в данный момент.
Делегируйте своих детей
Конструктор GridView.custom требует использования еще одного класса делегата. Тот, который предоставляет видимые виджеты, отображаемые в GridView в любой момент. Опять же, конструктору GridView.count предоставляется собственный дочерний делегат, и ему не нужно об этом беспокоиться. Снимок экрана конструктора GridView.count ниже показывает, что он использует класс с именем SliverChildListDelegate, который расширяет класс SliverChildDelegate. Именно этот класс принимает определенный список виджетов, чтобы затем отображать их соответствующим образом, пока GridView прокручивает их.
Когда вам предоставляется явный список уже определенных виджетов, рекомендуется использовать класс SliverChildListDelegate, а также конструктор GridView.count. Хотя иметь уже определенный список явно неэффективно. Особенно, если он действительно большой. В конце концов, в GridView одновременно можно просматривать только определенное количество объектов. Остальные просто занимают память. Чтобы избежать создания большего количества виджетов, чем отображается, рекомендуется вместо этого использовать класс SliverChildBuilderDelegate, как и конструктор GridView.builder. Видите здесь образец? Ниже приведен снимок экрана конструктора GridView.builder.
Просто щепка
При просмотре виджетов в GridView вы видите то, что Google называет «полосками» в области просмотра GridView. Другими словами, описанный выше класс «Sliver Child Delegate» отвечает за создание «полос» (видимых виджетов) для области просмотра GridView.
Внутри класса SliverChildListDelegate (см. Ниже) список виджетов, в свою очередь, вносится для создания соответствующего объекта Sliver. В коде на каждый виджет ссылается переменная child, и каждый далее «оборачивается» или заключен в дополнительный объект класса в зависимости от логических значений трех именованных параметров: addAutomaticKeepAlives , addRepaintBoundaries и addSemanticIndexes. Вы можете увидеть это ниже.
Еще несколько параметров
Эти три являются одними из немногих, которые нам еще предстоит изучить, мы сделаем это быстро, оставив только три.
addRepaintBoundaries
По умолчанию установлено значение true. Это означает, что ленты не «перекрашиваются», если и когда они возвращаются в поле зрения. Как бы то ни было, в этом простом примере для этого именованного параметра можно легко установить значение false, поскольку они вообще не прокручиваются, и поэтому не требуется «перерисовка».
addAutomaticKeepAlives
Если установлено значение true, фрагменты сохраняются в памяти, хотя в противном случае они были бы собраны мусором при прокрутке за пределами экрана и вне поля зрения. По умолчанию установлено значение true, но следует рассматривать значение false, чтобы освободить память очень-очень больших списков.
addSemanticIndexes
Позволяет акустическому программному обеспечению объявлять значения виджета при использовании людьми с ослабленным зрением. По умолчанию также установлено значение true, что обеспечивает индексацию, необходимую для правильной работы такого программного обеспечения.
Простой пример образца
Давайте посмотрим, как конструктор GridView.custom будет использоваться для воссоздания нашего простого примера. Как вы видите ниже, классу SliverChildListDelegate передается список виджетов. Довольно прямолинейно. Когда бы вы использовали конструктор GridView.custom? Лично я бы не стал очевидным. Это было бы только тогда, когда мне по той или иной причине нужен пользовательский ‘SliverChildDelegate’, а этого еще не произошло.
До какой степени?
Последний конструктор, который мы рассмотрим, - это GridView.extent. Например, GridView.count, он используется чаще, и вы можете увидеть выше, как он реализован, чтобы передать наш простой пример. Довольно прямолинейно. Однако что такое именованный параметр maxCrossAxisExtent? Что ж, мы можем быстро увидеть роль, которую он играет, если удвоить текущее значение с 200 до 400. См. Ниже.
Мы видим, что сейчас недостаточно места для двух столбцов, но отображается только один столбец с большими зелеными прямоугольниками. Следовательно, теперь вы можете прокручивать эти поля вверх и вниз. В отличие от конструктора GridView.count с явно переданным ему счетчиком по осям (в нашем случае это число 2), GridView.extent фактически вычисляет счет в своем делегате сетки, SliverGridDelegateWithMaxCrossAxisExtent . На снимке экрана ниже рассчитанное количество равно 1. Обратите внимание, что доступное количество пикселей, составляющих поперечную ось конкретного устройства, находится в свойстве constraints.crossAxisExent. Вы можете увидеть это значение для моего устройства ниже.
По сути, вы разбиваете количество доступных пикселей вдоль поперечной оси на указанное число «экстентов» плюс любой интервал между осями. В нашем случае интервал между осями установлен на 10. Посмотрите, что происходит, когда я избавляюсь от указанного отступа, предоставляя виджету больше места для работы.
Обратите внимание, что «доступное» количество пикселей на поперечной оси увеличилось, что позволяет значению «экстент» произвести счетчик до 2 - возвращаясь к двум столбцам.
Нужен кеш
Именованный параметр cacheExtent описывает, на сколько пикселей занимает область кэша до переднего края и после заднего края области просмотра. Лепестки, попадающие в эту область кэша, создаются в памяти (при возможной прокрутке до просмотра) или сохраняются в памяти (при прокрутке вне поля зрения), даже если они не видны на экране.
На самом деле Flutter предоставляет значение «кеша» по умолчанию 250,00. В зависимости от ваших конкретных потребностей вы можете изменить эту сумму. Однако оно не может быть равным нулю или меньше.
Это перетаскивание
Последний именованный параметр, dragStartBehavior, может иметь один из двух возможных перечислимых типов: DragStartBehavior.start и DragStartBehavior.down. По умолчанию установлено значение DragStartBehavior.start. Это означает, что поведение перетаскивания при прокрутке начнется при обнаружении жеста перетаскивания. Если установлено значение
DragStartBehavior.down, поведение при перетаскивании при прокрутке начнется при первом обнаружении события щелчка мыши. Говорят, что установка DragStartBehavior.start сделает анимацию перетаскивания более плавной. В то время как DragStartBehavior.down, как утверждается, сделает "поведение перетаскивания при прокрутке" немного более реактивным.
Каково ваше мнение?
В конце концов, казалось бы, конструктор GridView.count был наиболее подходящим для использования в таком простом примере. При более сложных макетах сетки и / или с огромным количеством отображаемых виджетов конструкторы GridView.builder и даже GridView.custom были бы лучшим выбором.
Со всеми конструкторами все сводится к генерации как делегата сетки (определяет макет сетки), так и дочернего делегата (виджеты в Slivers), а затем их передачи, наконец, виджету SliverGrid, который отвечает за создание "представления сетки", которое вы видите.
TL;DR
Позвольте мне отослать вас к еще одному примеру, написанному Srikanth относительно GridView, и это множество вариантов конструктора. Просто еще один простой пример, который вы можете скачать и поиграть.
Я немного изменил его пример, просто ограничив содержимое «дочернего виджета», постоянно находящееся в каждом примере GridView, в свойстве с именем sampleContainer. Затем вы можете увидеть «различия» в каждом из них на более коротком фрагменте кода в примере кода, который вы можете загрузить.
Наконец, как указано в документации GridView: «Если GridView больше не достаточно, например, потому что представление прокрутки должно иметь как сетку, так и список, или потому что сетка должна быть объединена с SliverAppBar и т. Д., Это просто перенести код с использования GridView на использование CustomScrollView напрямую ».
CustomScrollView действительно предоставляет вам еще несколько вариантов, но GridView, безусловно, останется важным инструментом в вашем наборе инструментов Flutter.
Ваше здоровье.
- Исходный код от 27 ноября 2019 г.
Дополнительные статьи, которые могут вас заинтересовать.