Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое адаптивная верстка?
Адаптивная верстка (Responsive Layout) — это подход к проектированию пользовательского интерфейса, при котором приложение автоматически подстраивается под размеры экрана устройства. Вместо создания отдельных версий для разных устройств, одна верстка гибко изменяется в зависимости от ширины экрана.
Ключевые концепции
Основные принципы адаптивной верстки:
- Гибкая сетка (Flexible Grid) — использование относительных единиц (процентов, rem) вместо пиксельных значений
- Медиа-запросы (Media Queries) — применение разных стилей для разных размеров экрана
- Гибкие изображения — изображения масштабируются пропорционально ширине контейнера
- Mobile-first подход — сначала разрабатываем для мобильного устройства, затем расширяем для больших экранов
В контексте Flutter
Fu utter предоставляет встроенные инструменты для создания адаптивного интерфейса:
import package:flutter/material.dart;
class ResponsiveLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final isMobile = screenWidth < 600;
final isTablet = screenWidth >= 600 && screenWidth < 1200;
final isDesktop = screenWidth >= 1200;
return Scaffold(
body: isMobile
? MobileLayout()
: isTablet
? TabletLayout()
: DesktopLayout(),
);
}
}
class MobileLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
Header(),
Content(),
Footer(),
],
),
);
}
}
Важные классы и методы
MediaQuery — основной класс для получения информации об экране:
final mediaQuery = MediaQuery.of(context);
final screenSize = mediaQuery.size; // Size(width, height)
final screenWidth = mediaQuery.size.width;
final screenHeight = mediaQuery.size.height;
final devicePixelRatio = mediaQuery.devicePixelRatio;
final isPortrait = mediaQuery.orientation == Orientation.portrait;
final isLandscape = mediaQuery.orientation == Orientation.landscape;
final padding = mediaQuery.padding; // Для notch и status bar
final viewInsets = mediaQuery.viewInsets; // Для клавиатуры
LayoutBuilder — более гибкий способ реагировать на размеры родительского виджета:
LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth < 600) {
return MobileLayout();
} else {
return DesktopLayout();
}
},
)
Практические примеры
Адаптивная колонка с перемещением элементов:
class AdaptiveRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isMobile = MediaQuery.of(context).size.width < 600;
return isMobile
? Column(
children: [
Sidebar(),
MainContent(),
],
)
: Row(
children: [
Expanded(flex: 1, child: Sidebar()),
Expanded(flex: 3, child: MainContent()),
],
);
}
}
Адаптивные отступы и размеры:
double getResponsivePadding(BuildContext context) {
final width = MediaQuery.of(context).size.width;
if (width < 600) return 16;
if (width < 1200) return 24;
return 32;
}
class PaddedContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(getResponsivePadding(context)),
child: Container(),
);
}
}
Типичные точки останова (Breakpoints)
const mobile = 480; // Small phones
const tablet = 768; // Tablets
const desktop = 1200; // Desktops
const largeDesktop = 1920; // Large screens
Лучшие практики
- Всегда использовать MediaQuery для получения реального размера экрана
- Тестировать на разных устройствах — ориентация, размер notch, клавиатура
- Не забывать про padding и viewInsets — они важны для корректной работы при наличии notch или на-экранной клавиатуры
- Использовать FractionallySizedBox для процентного размера
- Избегать жёстко закодированных значений — всегда использовать относительные размеры
Адаптивная верстка — это не опция, а требование при разработке современных мобильных приложений на Flutter. Правильная реализация обеспечивает хороший пользовательский опыт на всех устройствах.