Код-ревью Middle Вёрстка и constraints обновлено

Код-ревью: экран ленты

Вопрос

Экран ленты с шапкой, сеткой категорий и списком постов. Найдите проблемы раскладки и производительности.

Widget build(BuildContext context) {
  final width = MediaQuery.of(context).size.width;
  return SingleChildScrollView(
    child: Column(children: [
      Container(height: 200, width: width, child: const Header()),
      GridView.count(
        crossAxisCount: width > 600 ? 4 : 2,
        shrinkWrap: true,
        children: categories.map((c) => CategoryTile(c)).toList(),
      ),
      ListView(
        shrinkWrap: true,
        children: posts.map((p) => PostCard(p)).toList(),
      ),
    ]),
  );
}

Коротко

Правильная структура: CustomScrollView(slivers: [SliverToBoxAdapter(child: Header()), SliverGrid(...), SliverList.builder(...)]). Всё лениво и в одной прокрутке, без shrinkWrap.

Что должен найти ревьюер

  1. Производительностьстрока 2
    MediaQuery.of(context) подписывает на все изменения: клавиатура и отступы вызовут перестроение. Использовать MediaQuery.sizeOf(context).
  2. Производительностьстрока 11
    Список постов с shrinkWrap внутри SingleChildScrollView строит все посты сразу: ленивость потеряна. Нужен CustomScrollView с SliverList.builder.
  3. Ошибкастрока 6
    Вложенные GridView и ListView перехватывают прокрутку: внутренний скролл конфликтует с внешним. Нужно NeverScrollableScrollPhysics или, лучше, слайверы.
  4. Стильстрока 5
    Container только ради размеров: SizedBox(height: 200) проще, width: width не нужен, Column и так растягивает по ширине через crossAxisAlignment.stretch.
  5. Стильстрока 13
    Нет ключей у постов, при обновлении ленты состояния карточек (раскрытие, лайк в процессе) могут перепутаться.

Разбор

Правильная структура: CustomScrollView(slivers: [SliverToBoxAdapter(child: Header()), SliverGrid(...), SliverList.builder(...)]). Всё лениво и в одной прокрутке, без shrinkWrap. Ширину читать через MediaQuery.sizeOf или SliverLayoutBuilder.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме