← Назад к вопросам
Какие знаешь виджеты которые позволяют верстать адаптивный под размер экранов интерфейс?
2.2 Middle🔥 211 комментариев
#Flutter виджеты#Архитектура Flutter
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Виджеты для адаптивного дизайна в Flutter
Flutter предоставляет множество инструментов для создания интерфейсов, которые адаптируются к размерам экранов. Рассмотрим основные виджеты и подходы.
1. MediaQuery — основа адаптивности
Получение информации о размерах экрана и ориентации:
class ResponsiveWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Получаем размер экрана
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
final orientation = MediaQuery.of(context).orientation;
// Адаптируем под размер
if (screenWidth < 600) {
return MobileLayout();
} else if (screenWidth < 900) {
return TabletLayout();
} else {
return DesktopLayout();
}
}
}
2. LayoutBuilder — адаптация по доступному пространству
Получает размеры родительского контейнера:
LayoutBuilder(
builder: (context, constraints) {
// constraints.maxWidth — максимальная доступная ширина
if (constraints.maxWidth < 600) {
return Column( // Узкая колонка
children: [
Text("Mobile Layout"),
Image.asset("image.jpg"),
],
);
} else {
return Row( // Широкий ряд
children: [
Image.asset("image.jpg"),
Text("Desktop Layout"),
],
);
}
},
)
3. Expanded и Flexible — распределение пространства
Позволяют компонентам занимать доступное пространство:
Row(
children: [
// Занимает 1/3 пространства
Expanded(
flex: 1,
child: Container(color: Colors.red),
),
// Занимает 2/3 пространства
Expanded(
flex: 2,
child: Container(color: Colors.blue),
),
],
)
// Flexible (мягче) — сжимается, но не расширяется
Flexible(
child: Text("Может переносить текст"),
)
4. FractionallySizedBox — размер в процентах
Устанавливает размер как долю родителя:
FractionallySizedBox(
widthFactor: 0.8, // 80% ширины родителя
heightFactor: 0.5, // 50% высоты родителя
child: Container(
color: Colors.amber,
child: Text("Адаптивный контейнер"),
),
)
5. SingleChildScrollView — прокрутка на малых экранах
Предотвращает переполнение при недостатке места:
SingleChildScrollView(
child: Column(
children: [
// Много элементов
for (int i = 0; i < 50; i++)
Text("Item $i"),
],
),
)
6. GridView — адаптивная сетка
Автоматически подстраивает количество столбцов:
// Фиксированное количество столбцов
GridView.count(
crossAxisCount: 2, // 2 столбца
children: List.generate(10, (i) => Card(child: Text("Item $i"))),
)
// Адаптивная сетка по размерам элементов
GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200, // Каждый элемент макс 200px
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: 20,
itemBuilder: (context, i) => Card(child: Text("Item $i")),
)
7. Wrap — автоматическое переносу элементов
Элементы переносятся на новую строку при недостатке места:
Wrap(
spacing: 10.0, // Расстояние между элементами
runSpacing: 10.0, // Расстояние между строками
children: [
Chip(label: Text("Tag 1")),
Chip(label: Text("Tag 2")),
Chip(label: Text("Tag 3")),
// Элементы автоматически переносятся
],
)
8. Практический пример: полностью адаптивный интерфейс
class ResponsiveApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: LayoutBuilder(
builder: (context, constraints) {
final isMobile = constraints.maxWidth < 600;
final isTablet = constraints.maxWidth >= 600 && constraints.maxWidth < 900;
final isDesktop = constraints.maxWidth >= 900;
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(isMobile ? 8.0 : 16.0),
child: Column(
children: [
// Адаптивный заголовок
Text(
"Заголовок",
style: TextStyle(
fontSize: isMobile ? 20 : (isTablet ? 28 : 36),
),
),
SizedBox(height: isMobile ? 8 : 16),
// Адаптивная сетка
GridView.count(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
crossAxisCount: isMobile ? 1 : (isTablet ? 2 : 3),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
children: List.generate(
6,
(i) => Card(
child: Center(child: Text("Item $i")),
),
),
),
],
),
),
);
},
),
),
);
}
}
9. Material Design 3: ResponsiveRowColumn
Модифицирует layout в зависимости от ориентации:
final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
final sizes = ResponsiveRowColumnSizes(
lg: [6, 6], // Desktop: 50-50
md: [12], // Tablet: 100%
sm: [12], // Mobile: 100%
);
10. Размеры и breakpoints
class Breakpoints {
static const mobile = 480;
static const tablet = 768;
static const desktop = 1024;
static const largeDesktop = 1280;
}
// Использование
if (screenWidth <= Breakpoints.mobile) {
// Mobile layout
} else if (screenWidth <= Breakpoints.tablet) {
// Tablet layout
} else if (screenWidth <= Breakpoints.desktop) {
// Desktop layout
} else {
// Large desktop layout
}
Итого
Ключевые виджеты для адаптивного дизайна:
- MediaQuery — информация об экране
- LayoutBuilder — адаптация по доступному пространству
- Expanded/Flexible — распределение пространства
- GridView — адаптивная сетка
- Wrap — автопереносу элементов
- FractionallySizedBox — размеры в процентах
Комбинируя эти виджеты, можно создавать полностью адаптивные интерфейсы, работающие на любых размерах экранов.