Привет, если вы на пути изучения Flutter/Dart или вам просто интересно почитать про путь изучения, подписывайтесь на мой канал в telegram, буду рад вас видеть! А сегодня поговорим про взаимодействие с виджетами во Flutter!
Предыдущая статья: Работа с виджетами Flutter | 1 часть
Содержание
Использование Center виджета
Проблема
Вы хотите убедиться, что информация размещена по центру экрана.
Решение
Используйте виджет Center для выравнивания дочернего элемента на экране. Вот пример того, как использовать виджет Center для выравнивания по пересечению горизонтальной и вертикальной осей:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Center Widget Demo';
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatelessWidget(),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Center Example')),
body: _buildCenterWidget(),
);
}
Widget _buildCenterWidget() {
return const Center(
child: Text(
"Top Five Spoken Languages - 2022",
style: TextStyle(fontSize: 30, color: Colors.grey),
),
);
}
}
Обсуждение
В примере код демонстрирует применение центрального виджета к текстовому виджету на экране. Центральный виджет обеспечивает перемещение текста непосредственно в центр доступного пространства экрана, указанного элементом Scaffold body, как показано на рисунке 9-7.
В примере показано, как можно использовать виджет по центру для выравнивания содержимого на экране. В большинстве ситуаций вам потребуется комбинировать этот виджет с другими методами для достижения желаемого результата.
Центральный виджет предоставляет отличный способ центрирования экранных объектов. Несмотря на то, что он относительно прост в использовании в приложении, не стоит недооценивать его возможности. Его можно использовать в сочетании с широким спектром виджетов для получения различных результатов. В более сложных макетах это может быть не единственное требуемое решение, но оно определенно сэкономит вам время на этапе разработки.
Использование SizedBox
Проблема
Вы хотите добавить пробелы в пользовательский интерфейс.
Решение
Используйте виджет SizedBox, чтобы применить определенное пространство к экранному интерфейсу.
Вот пример, в котором мы применяем определенный макет к пользовательскому интерфейсу. Для структурирования макета используется поле SizedBox с настройками ширины и высоты:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'SizedBox Widget Demo';
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatelessWidget(),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('SizedBox Example')),
body: _buildSizedBoxWidget(),
);
}
Widget _buildSizedBoxWidget() {
return SingleChildScrollView(
padding: const EdgeInsets.all(10.0),
child: Column(
children: const [
SizedBox(
width: 200,
height: 100,
child: Card(
color: Colors.amber,
child: Center(child: Text('Developer'))),
),
SizedBox(
width: 300,
height: 100,
child: Card(
color: Colors.green,
child: Center(child: Text('Flutter Framework'))),
),
SizedBox(
width: 400,
height: 100,
child: Card(
color: Colors.blue,
child: Center(child: Text('Dart SDK'))),
),
],
),
);
}
}
Обсуждение
В примере SizedBox используется несколькими способами из-за его универсальности. На рисунке 9-8 три виджета SizedBox используются для иллюстрации взаимодействия между developer, Flutter и Dart.
Обычно SizedBox используется для обеспечения точного контроля над расположением виджетов. Поскольку SizedBox поддерживает свойства как высоты, так и ширины, вы можете добиться очень точного контроля над позиционированием элементов на экране.
Однако SizedBox можно использовать в самых разных ситуациях, в которых вы могли бы увидеть виджет контейнера. Если вашему приложению просто требуются пробелы (т.е. заполнить пробелы в определенной пропорции), рекомендуется использовать SizedBox. Эта рекомендация основана на сравнении производительности между двумя виджетами, где SizedBox имеет (небольшое) преимущество.
Думайте о SizedBox как об улучшенном Container виджете, и вы, скорее всего, будете на правильном пути. Поэтому избегайте комбинирования SizedBox и Container виджетов - используйте один или другой. В дополнение к высоте и ширине, SizedBox также поддерживает дочернее свойство, позволяющее расширять его за счет включения других виджетов.
Как виджет с пробелами, SizedBox намеренно не отображается по умолчанию. Однако он поддерживает дочерний элемент, позволяющий встраивать в него другие виджеты. В примере кода SizedBox включает в себя виджет Card, использующий дочернее свойство, поэтому можно применить цвет. Если вам нужен цвет для применения, вы все равно можете рассмотреть возможность использования контейнера, поскольку по умолчанию это не поддерживается в SizedBox.
Использование Column
Проблема
Вам нужен гибкий виджет для отображения в виде вертикального макета на экране.
Решение
Используйте виджет столбцов, чтобы информация отображалась в виде вертикального массива.
Вот пример того, как использовать виджет столбцов в Flutter для адаптивного отображения содержимого на экране:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Center Widget Demo';
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatelessWidget(),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Center Example')),
body: _buildCenterWidget(),
);
}
Widget _buildCenterWidget() {
return Column(
children: [
const SizedBox(height: 10.0),
const Center(
child: Text("Top Five Spoken Languages - 2022",
style: TextStyle(fontSize: 30, color: Colors.grey))),
const SizedBox(height: 20.0),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(children: [
const SizedBox(
width: 100.0,
child: Text("English"),
),
Container(
width: 600.0,
color: Colors.green,
child: const Center(
child: Text("1.3 Billion",
style: TextStyle(fontSize: 18, color: Colors.white))),
),
]),
const SizedBox(height: 10.0),
Row(children: [
const SizedBox(
width: 100.0,
child: Text("Mandarin"),
),
Container(
width: 550.0,
color: Colors.orange,
child: const Center(
child: Text("1 Billion",
style: TextStyle(fontSize: 18, color: Colors.white))),
),
]),
const SizedBox(height: 10.0),
Row(children: [
const SizedBox(
width: 100.0,
child: Text("Hindi"),
),
Container(
width: 300.0,
color: Colors.pink,
child: const Center(
child: Text("600 Million",
style: TextStyle(fontSize: 18, color: Colors.white))),
),
]),
const SizedBox(height: 10.0),
Row(children: [
const SizedBox(
width: 100.0,
child: Text("Spanish"),
),
Container(
width: 280.0,
color: Colors.cyan,
child: const Center(
child: Text("540 Million",
style: TextStyle(fontSize: 18, color: Colors.white))),
),
]),
const SizedBox(height: 10.0),
Row(children: [
const SizedBox(
width: 100.0,
child: Text("Arabic"),
),
Container(
width: 140.0,
color: Colors.deepPurple,
child: const Center(
child: Text("270 Million",
style: TextStyle(fontSize: 18, color: Colors.white))),
),
]),
]),
)
],
);
}
}
Обсуждение
В примере кода виджет Column используется для построения интерфейса столбчатой диаграммы, представляющей пять самых распространенных языков в мире по состоянию на 2022 год, как показано на Рисунок. 9-9.
Область, определенная для столбца, определяется как SingleChildScrollView, чтобы гарантировать, что экран остается отзывчивым и будет отображаться корректно. Свойства распределения высоты и ширины применяются в виджете SizedBox для каждого элемента и используются для ограничения области, доступной в виджете Column.
Когда в пользовательском интерфейсе применяется ограничение, виджет попытается динамически обработать представленные изменения. В некоторых ситуациях изменения не могут быть отображены корректно, что приводит к ошибке переполнения.
Переполнения являются очень распространенной ошибкой и отображаются на экране в виде серии желтых и черных полос. Такая ошибка сопровождается предупреждением о переполнении, указывающим причину возникновения ошибки. Чтобы понять параметры, применимые к ограничениям, обратитесь к документации Flutter. В примере используется виджет SingleChildScrollView, чтобы гарантировать, что ошибка переполнения не повлияет на код.
При использовании виджета столбцов вы можете выровнять содержимое по осям x (горизонтальной) и yaxis (вертикальной). Выравнивание по горизонтали (оси x) включено с помощью функции выравнивания по поперечной оси. Используйте это выравнивание, чтобы размещать содержимое в определенном положении на экране, например в начале, центре или конце.
Используйте свойство mainAxisAlignment для выравнивания по оси y. Выравнивание гарантирует, что свободное пространство равномерно распределено между дочерними элементами, в том числе до и после первого/последнего дочернего элемента в массиве. mainAxisAlignment также поддерживает свойства start, center и end для смещения привязки оси y.
Виджеты столбцов и строк имеют много общего.
Использование Row
Проблема
Вам нужен гибкий виджет для отображения в виде горизонтального макета на экране.
Решение
Используйте виджет Row, чтобы разрешить отображение дочерних виджетов в виде горизонтального массива.
Вот пример того, как использовать виджет Row в Flutter для отображения информации на экране:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Example';
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatelessWidget(),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Row Example')),
body: _buildRowWidget(),
);
}
Widget _buildRowWidget() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
width: 5,
color: Colors.transparent,
),
Expanded(
child: Container(
height: 50,
width: 200,
color: Colors.red,
child: const Center(
child: Text("50"),
),
),
),
Expanded(
child: Container(
height: 100,
width: 200,
color: Colors.green,
child: const Center(
child: Text("100"),
),
),
),
Expanded(
child: Container(
height: 200,
width: 200,
color: Colors.orange,
child: const Center(
child: Text("200"),
),
),
),
Container(
width: 5,
color: Colors.transparent,
),
]);
}
}
Обсуждение
В примере кода строки данных создаются по горизонтали (ось x), как показано на рисунке 9-10. Виджеты строк являются статическими, что означает, что они не имеют возможности прокрутки без использования дополнительного виджета.
Если отображаемые данные выходят за пределы размеров экрана, они отображаются на экране в виде серии желтых и черных полос. В примере к отображаемому виджету применяется ограничение, поэтому он будет динамически подстраиваться под размер экрана. Чтобы понять параметры, применимые к ограничениям, обратитесь к документации Flutter.
Выравнивание по вертикали (по оси y) использует свойство mainAxisAlignment для использования начала экрана в качестве привязки. mainAxisAlignment поддерживает свойства start, center и end для смещения привязки оси y.
Выравнивание по горизонтали (по оси x) выполняется путем выравнивания по поперечной оси. Опять же, этот метод поддерживает свойства start, center и end для смещения привязки по оси x.
Использование Expanded виджета
Проблема
Вы хотите автоматически использовать все доступное пространство на экране.
Решение
Используйте расширенный виджет для координации доступного пространства, видимого пользователю (т.е. области просмотра).
Вот пример, в котором мы используем Extended виджет для определения трех экранных элементов, которые будут координироваться для использования доступных экранных размеров:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
const title = 'Expanded Widget';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body: const MyExpandedWidget(),
),
);
}
}
class MyExpandedWidget extends StatelessWidget {
const MyExpandedWidget();
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.transparent,
child: Center(
child: RichText(
text: const TextSpan(
text: 'Luxembourg',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
color: Colors.grey,
),
),
),
),
)),
Expanded(
child: Container(
color: Colors.blue,
),
),
],
);
}
}
Обсуждение
В примере кода Extended виджет используется для воссоздания флага Люксембурга, как показано на рисунке 9-11. Extended виджет заключен в виджет столбца, и каждой строке присвоен соответствующий цвет.
Несмотря на простоту Extended виджета, его можно использовать в самых разных вариантах использования. В примере вместо выполнения запроса к размерам на экране Extended виджет используется для автоматического заполнения доступного пространства. Расширенный (как следует из названия) автоматически увеличится до размеров экрана. Вам не нужно указывать пропорции; они будут рассчитываться динамически (т.е. автоматически).
В ситуации, когда ваше приложение захочет узнать, как соотнести распределение области просмотра между каждым элементом, Extended виджет может оказаться очень полезным. В этом случае расширенный виджет можно использовать для автоматического предоставления правильных размеров, доступных в области просмотра.
Примером того, где поведение Extended виджета может быть полезным, является работа со списками.
Если у вас есть виджет ListView и другой экранный виджет, и вы хотите отображать оба на экране, вам нужно будет указать виджетам, какой объем области просмотра они могут занимать. Обратитесь к примеру на рис. 9-12, в котором ListView попытается заполнить экран по умолчанию; если вы не хотите такого поведения, вам нужно будет использовать виджет для ограничения выделяемого пространства.
Используйте Extended виджет в сочетании с ListView, чтобы сообщить ему, что он должен использовать только оставшийся экран (т.е. видимую область пользователя на экране). Помните, что виджеты обычно обращаются к своим родительским элементам за указаниями по применяемым ограничениям, таким как высота и ширина.