- Оригинальный адрес:Flutter Layout Cheat Sheet
- Оригинальный автор:Томек Полански
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:EmilyQiRabbit
- Корректор:smilemuffie,suhanyujie
Вам нужно знать о простых шаблонах макетов Flutter? Теперь я покажу вам коллекцию фрагментов кода макета Flutter, которые я обобщил. Я постараюсь, чтобы код был коротким и простым для понимания, и я дам визуализацию. Но нам все равно нужно идти шаг за шагом — каталог шаблонов будет следовать постепенно. Я больше сосредоточусь на применении виджетов Flutter, а не просто на отображении виджетов (Flutter GalleryМолодец на этом этапе! ) Если у вас есть другие вопросы о макетах Flutter или вы хотите поделиться своим кодом, напишите мне!
содержание
- Строка и столбец
- Внутренняя ширина и внутренняя высота
- Stack
- Expanded
- ConstrainedBox
- Container
- Украшение (украшение): Boxdecormation
- Изображение (изображение): DecorationImage
- Граница (граница): Граница
- Радиус границы (borderRadius): BorderRadius
- Форма: Боксформа
- Тень (boxShadow):
List<BoxShadow>
- Градиент (градиент): RadialGradient
- Режим наложения фона (backgroundBlendMode): BlendMode
- SizedBox
- SafeArea
Строка и столбец
MainAxisAlignment
Row /*或 Column*/(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
Если вы хотите базовое выравнивание разных символов, вы должны использоватьCrossAxisAlignment.baseline
.
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: <Widget>[
Text(
'Baseline',
style: Theme.of(context).textTheme.display3,
),
Text(
'Baseline',
style: Theme.of(context).textTheme.body1,
),
],
),
CrossAxisAlignment
Row /*或 Column*/(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 200),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 200),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 200),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 200),
Icon(Icons.star, size: 50),
],
),
MainAxisSize
Row /*或 Column*/(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
Row /*或 Column*/(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
Внутренняя ширина и внутренняя высота
Хотите, чтобы все виджеты в строке или столбце имели ту же высоту/ширину, что и самый высокий/широкий виджет? Не ищите, ответ здесь!
Когда у вас есть этот стиль макета:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('IntrinsicWidth')),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Short'),
),
RaisedButton(
onPressed: () {},
child: Text('A bit Longer'),
),
RaisedButton(
onPressed: () {},
child: Text('The Longest text button'),
),
],
),
),
);
}
Но вы хотите, чтобы все кнопки исамый широкийкнопка и т.д.ширина, просто используйтеIntrinsicWidth
:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('IntrinsicWidth')),
body: Center(
child: IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Short'),
),
RaisedButton(
onPressed: () {},
child: Text('A bit Longer'),
),
RaisedButton(
onPressed: () {},
child: Text('The Longest text button'),
),
],
),
),
),
);
}
Если все, что вам нужно, это иметь все детали исамая высокая частьЖдатьвысоко, который можно комбинировать сIntrinsicHeight
а такжеRow
часть.
Stack
Отлично подходит для укладки деталей вместе
@override
Widget build(BuildContext context) {
Widget main = Scaffold(
appBar: AppBar(title: Text('Stack')),
);
return Stack(
fit: StackFit.expand,
children: <Widget>[
main,
Banner(
message: "Top Start",
location: BannerLocation.topStart,
),
Banner(
message: "Top End",
location: BannerLocation.topEnd,
),
Banner(
message: "Bottom Start",
location: BannerLocation.bottomStart,
),
Banner(
message: "Bottom End",
location: BannerLocation.bottomEnd,
),
],
);
}
Если вы хотите использовать свои собственные части, вам нужно поместить их вPositioned
в
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Stack')),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Material(color: Colors.yellowAccent),
Positioned(
top: 0,
left: 0,
child: Icon(Icons.star, size: 50),
),
Positioned(
top: 340,
left: 250,
child: Icon(Icons.call, size: 50),
),
],
),
);
}
Если вы не хотите угадывать верхние или нижние значения, вы можете использоватьLayoutBuilder
чтобы получить их
Widget build(BuildContext context) {
const iconSize = 50;
return Scaffold(
appBar: AppBar(title: Text('Stack with LayoutBuilder')),
body: LayoutBuilder(
builder: (context, constraints) =>
Stack(
fit: StackFit.expand,
children: <Widget>[
Material(color: Colors.yellowAccent),
Positioned(
top: 0,
child: Icon(Icons.star, size: iconSize),
),
Positioned(
top: constraints.maxHeight - iconSize,
left: constraints.maxWidth - iconSize,
child: Icon(Icons.call, size: iconSize),
),
],
),
),
);
}
Expanded
Expanded
может иFlex\FlexboxМакеты работают вместе и отлично подходят для выделения места для нескольких элементов.
Row(
children: <Widget>[
Expanded(
child: Container(
decoration: const BoxDecoration(color: Colors.red),
),
flex: 3,
),
Expanded(
child: Container(
decoration: const BoxDecoration(color: Colors.green),
),
flex: 2,
),
Expanded(
child: Container(
decoration: const BoxDecoration(color: Colors.blue),
),
flex: 1,
),
],
),
ConstrainedBox
По умолчанию большинство компонентов занимают как можно меньше места:
Card(child: const Text('Hello World!'), color: Colors.yellow)
ConstrainedBox
Разрешить виджету использовать желаемое оставшееся пространство.
ConstrainedBox(
constraints: BoxConstraints.expand(),
child: const Card(
child: const Text('Hello World!'),
color: Colors.yellow,
),
),
вы можете использоватьBoxConstraints
Укажите, сколько места может занимать виджет, указавheight
/width
изmin
/max
Атрибуты.
BoxConstraints.expand
Позволит компоненту использовать неограниченное (все доступное) пространство, если не указано иное:
ConstrainedBox(
constraints: BoxConstraints.expand(height: 300),
child: const Card(
child: const Text('Hello World!'),
color: Colors.yellow,
),
),
Приведенный выше код эквивалентен следующему коду:
ConstrainedBox(
constraints: BoxConstraints(
minWidth: double.infinity,
maxWidth: double.infinity,
minHeight: 300,
maxHeight: 300,
),
child: const Card(
child: const Text('Hello World!'),
color: Colors.yellow,
),
),
Container
Один из наиболее часто используемых виджетов — и есть причина, по которой он так распространен:
Контейнер для инструментов компоновки
если вы не укажетеContainer
изheight
а такжеwidth
, это будет иchild
тот же размер
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container as a layout')),
body: Container(
color: Colors.yellowAccent,
child: Text("Hi"),
),
);
}
Если хочешьContainer
расширяется, чтобы быть равным его родительскому элементу, даheight
а такжеwidth
использование собственностиdouble.infinity
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container as a layout')),
body: Container(
height: double.infinity,
width: double.infinity,
color: Colors.yellowAccent,
child: Text("Hi"),
),
);
}
Оформление контейнера
Вы можете использовать свойство цвета, чтобы изменитьContainer
цвет фона, ноdecoration
а такжеforegroundDecoration
вы можете сделать больше. (Используя эти два свойства, вы можете полностью изменитьContainer
Внешний вид этой части, о котором я расскажу в продолжении, так как в этой части очень много контента)decoration
всегда ставится после дочернего элемента, аforegroundDecoration
затем вchild
над.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container.decoration')),
body: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(color: Colors.yellowAccent),
child: Text("Hi"),
),
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container.foregroundDecoration')),
body: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(color: Colors.yellowAccent),
foregroundDecoration: BoxDecoration(color: Colors.red.withOpacity(0.5)),
child: Text("Hi"),
),
);
}
Трансформация контейнера
Если вы не хотите использоватьTransform
виджет для изменения макета, вы можете использоватьContainer
изtransform
Атрибуты
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container.transform')),
body: Container(
height: 300,
width: 300,
transform: Matrix4.rotationZ(pi / 4),
decoration: BoxDecoration(color: Colors.yellowAccent),
child: Text(
"Hi",
textAlign: TextAlign.center,
),
),
);
}
BoxDecoration
Декоративные эффекты часто используются в компонентах-контейнерах для изменения внешнего вида компонента.
Изображение (изображение): DecorationImage
Использовать изображение в качестве фона:
Scaffold(
appBar: AppBar(title: Text('image: DecorationImage')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
image: DecorationImage(
fit: BoxFit.fitWidth,
image: NetworkImage(
'https://flutter.io/images/catalog-widget-placeholder.png',
),
),
),
),
),
);
Граница (граница): Граница
Задает стиль границы контейнера.
Scaffold(
appBar: AppBar(title: Text('border: Border')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
border: Border.all(color: Colors.black, width: 3),
),
),
),
);
Радиус границы (borderRadius): BorderRadius
Пусть границы будут закруглены.
если украшенshape
даBoxShape.circle
,ТакborderRadius
будет недействительным
Scaffold(
appBar: AppBar(title: Text('borderRadius: BorderRadius')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
border: Border.all(color: Colors.black, width: 3),
borderRadius: BorderRadius.all(Radius.circular(18))),
),
),
);
Форма: Боксформа
Форма коробки может быть прямоугольником, квадратом, эллипсом или кругом.
Для других произвольных форм вы должны использоватьShapeDecoration
вместоBoxDecoration
Scaffold(
appBar: AppBar(title: Text('shape: BoxShape')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
shape: BoxShape.circle,
),
),
),
);
Тень (boxShadow):List<BoxShadow>
Тени могут быть добавлены к контейнерам.
Этот параметр представляет собой список, поэтому вы можете определить несколько различных оттенков, а затем сгруппировать их вместе.
Scaffold(
appBar: AppBar(title: Text('boxShadow: List<BoxShadow>')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.yellow,
boxShadow: const [
BoxShadow(blurRadius: 10),
],
),
),
),
);
градиент
Существует три типа градиентов:LinearGradient
,RadialGradient
а такжеSweepGradient
.
Scaffold(
appBar: AppBar(title: Text('gradient: LinearGradient')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: const [
Colors.red,
Colors.blue,
],
),
),
),
),
);
Scaffold(
appBar: AppBar(title: Text('gradient: RadialGradient')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
gradient: RadialGradient(
colors: const [Colors.yellow, Colors.blue],
stops: const [0.4, 1.0],
),
),
),
),
);
Scaffold(
appBar: AppBar(title: Text('gradient: SweepGradient')),
body: Center(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
gradient: SweepGradient(
colors: const [
Colors.blue,
Colors.green,
Colors.yellow,
Colors.red,
Colors.blue,
],
stops: const [0.0, 0.25, 0.5, 0.75, 1.0],
),
),
),
),
);
Режим наложения фона (backgroundBlendMode)
backgroundBlendMode
даBoxDecoration
Самое сложное свойство в .
это можно смешатьBoxDecoration
цвета и градиенты, и независимо отBoxDecoration
На каких элементах.
имеютbackgroundBlendMode
,вы можете использоватьBlendMode
Длинный список алгоритмов в перечислимом типе.
Сначала настройтеBoxDecoration
дляforegroundDecoration
, который отображается вContainer
Дочерний элемент выше (иdecoration
отображается после дочерних элементов).
Scaffold(
appBar: AppBar(title: Text('backgroundBlendMode')),
body: Center(
child: Container(
height: 200,
width: 200,
foregroundDecoration: BoxDecoration(
backgroundBlendMode: BlendMode.exclusion,
gradient: LinearGradient(
colors: const [
Colors.red,
Colors.blue,
],
),
),
child: Image.network(
'https://flutter.io/images/catalog-widget-placeholder.png',
),
),
),
);
backgroundBlendMode
влияет не только наContainer
.
backgroundBlendMode
может измениться сContainer
Цвет любого виджета в дереве виджетов.
В следующем коде есть родительский элементContainer
, который отображает изображениеimage
и один б/уbackgroundBlendMode
дочерний элементContainer
. Вы по-прежнему получите тот же эффект, что и в предыдущем фрагменте кода.
Scaffold(
appBar: AppBar(title: Text('backgroundBlendMode')),
body: Center(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://flutter.io/images/catalog-widget-placeholder.png',
),
),
),
child: Container(
height: 200,
width: 200,
foregroundDecoration: BoxDecoration(
backgroundBlendMode: BlendMode.exclusion,
gradient: LinearGradient(
colors: const [
Colors.red,
Colors.blue,
],
),
),
),
),
),
);
SizedBox
Это самый простой, но самый полезный виджет
SizeBox используется как ConstrainedBox
SizedBox
может быть достигнуто иConstrainedBox
аналогичный эффект
SizedBox.expand(
child: Card(
child: Text('Hello World!'),
color: Colors.yellowAccent,
),
),
SizeBox используется в качестве заполнения
Если вам нужно добавить отступы или поля, вы можете выбратьPadding
илиContainer
часть. Но они не так хороши, как добавлениеSizedbox
легко читать
Column(
children: <Widget>[
Icon(Icons.star, size: 50),
const SizedBox(height: 100),
Icon(Icons.star, size: 50),
Icon(Icons.star, size: 50),
],
),
SizedBox используется как невидимый объект
Много раз вы хотите передать логическое значение (bool
) для управления отображением и скрытием компонентов
Widget build(BuildContext context) {
bool isVisible = ...
return Scaffold(
appBar: AppBar(
title: Text('isVisible = $isVisible'),
),
body: isVisible
? Icon(Icons.star, size: 150)
: const SizedBox(),
);
}
из-заSizedBox
есть одинconst
конструктор, использоватьconst SizedBox()
становится очень простым.
Более простым решением является использованиеOpacity
компоненты, а затемopacity
изменить значение на0.0
. Недостаток этого решения в том, что хотя компонент и невидим, он все равно занимает место.
SafeArea
На разных платформах есть много специальных позиций, таких как строка состояния системы Android или «обрезанная челка» iPhone X, и нам следует избегать размещения элементов в этих позициях.
Решение заключается в использованииSafeArea
компоненты (следующие примеры используются и не используютсяSafeArea
Эффект)
Widget build(BuildContext context) {
return Material(
color: Colors.blue,
child: SafeArea(
child: SizedBox.expand(
child: Card(color: Colors.yellowAccent),
),
),
);
}
Ждем больше контента
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.