Код-ревью 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.
Что должен найти ревьюер
- Производительностьстрока 2
MediaQuery.of(context)подписывает на все изменения: клавиатура и отступы вызовут перестроение. ИспользоватьMediaQuery.sizeOf(context). - Производительностьстрока 11Список постов с
shrinkWrapвнутриSingleChildScrollViewстроит все посты сразу: ленивость потеряна. НуженCustomScrollViewсSliverList.builder. - Ошибкастрока 6Вложенные
GridViewиListViewперехватывают прокрутку: внутренний скролл конфликтует с внешним. НужноNeverScrollableScrollPhysicsили, лучше, слайверы. - Стильстрока 5
Containerтолько ради размеров:SizedBox(height: 200)проще,width: widthне нужен,Columnи так растягивает по ширине черезcrossAxisAlignment.stretch. - Стильстрока 13Нет ключей у постов, при обновлении ленты состояния карточек (раскрытие, лайк в процессе) могут перепутаться.
Разбор
Правильная структура: CustomScrollView(slivers: [SliverToBoxAdapter(child: Header()), SliverGrid(...), SliverList.builder(...)]). Всё лениво и в одной прокрутке, без shrinkWrap. Ширину читать через MediaQuery.sizeOf или SliverLayoutBuilder.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Flutter: MediaQuery.sizeOf против MediaQuery.of
Следующий вопрос
Flutter: жёлто-чёрная полоса в Row