Начинаем новую неделю с очередной интерпретации официальной документации Flutter в формате «вопрос-ответ». 4-я часть освещает в сравнительном стиле Flutter для веб-разработчиков. Она целиком посвящена вёрстке и вышла не такой объёмной, как предыдущие. Традиционно рекомендую всем интересующимся Flutter веб-разработчикам заглянуть под кат, чтобы понять, стоит ли пробовать этот фреймворк и сколько усилий это займёт.
Если информации здесь будет недостаточно или у вас есть опыт в нативной разработке под конкретную платформу, то рекомендую заглянуть в другие части:
Flutter. Часть 1. Для Android-разработчиков
Flutter. Часть 2. Для iOS-разработчиков
Flutter. Часть 3. Для React Native-разработчиков
Flutter. Часть 4. Для Web-разработчиков
Flutter. Часть 5. Для Xamarin.Forms-разработчиков
Содержание:
- Базовая вёрстка
- Как стилизовать и выравнивать текст?
- Как устанавливается цвет фона?
- Как центрировать компоненты?
- Как установить ширину контейнера?
- Позиции и размеры
- Как устанавливать абсолютную позицию?
- Как задавать вращение компонентам?
- Как скейлить компоненты?
- Как применить градиент?
- Форма
- Текст
- Как регулировать расстояние между текстом?
- Как форматировать часть текста?
- Как ограничить показ длинного текста?
Базовая вёрстка
Вопрос:
Как стилизовать и выравнивать текст?
Ответ:
С помощью TextStyle.
Пример:
HTML/CSS
<div class="greybox">
Lorem ipsum
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Georgia;
}
Flutter
var container = Container( // grey box
child: Text(
"Lorem ipsum",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w900,
fontFamily: "Georgia",
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Вопрос:
Как устанавливается цвет фона?
Ответ
С помощью класса BoxDecoration.
Отличия
Свойство background-color
в CSS отвечает только за цвет фона. BoxDecoration отвечает за более широкий спектр свойств, например скругление углов, окантовку и т.п.
Пример
HTML/CSS
<div class="greybox">
Lorem ipsum
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
}
Flutter
var container = Container( // grey box
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
width: 320,
height: 240,
decoration: BoxDecoration(
color: Colors.grey[300],
),
);
Вопрос:
Как центрировать компоненты?
Ответ
С помощью виджета Center.
Пример
HTML/CSS
<div class="greybox">
Lorem ipsum
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
Flutter
var container = Container( // grey box
child: Center(
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Вопрос:
Как установить ширину контейнера?
Ответ
С помощью свойства width
.
Отличия
У виджетов Flutter свойство width
фиксировано. Чтобы настроить maxWidth
или minWidth
, используется виджет BoxConstraints.
Пример:
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
width: 100%;
max-width: 240px;
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red box
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
decoration: BoxDecoration(
color: Colors.red[400],
),
padding: EdgeInsets.all(16),
width: 240, //max-width is 240
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Позиции и размеры
Вопрос
Как устанавливать абсолютную позицию?
Ответ
С помощью виджета Positioned внутри виджета Stack.
Дополнительная информация
По умолчанию виджеты позиционируются внутри родительских виджетов.
Пример
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
position: relative;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
position: absolute;
top: 24px;
left: 24px;
}
Flutter
var container = Container( // grey box
child: Stack(
children: [
Positioned( // red box
child: Container(
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
decoration: BoxDecoration(
color: Colors.red[400],
),
padding: EdgeInsets.all(16),
),
left: 24,
top: 24,
),
],
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Вопрос
Как задавать вращение компонентам?
Ответ
С помощью виджета Transform.
Пример
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
transform: rotate(15deg);
}
Flutter
var container = Container( // gray box
child: Center(
child: Transform(
child: Container( // red box
child: Text(
"Lorem ipsum",
style: bold24Roboto,
textAlign: TextAlign.center,
),
decoration: BoxDecoration(
color: Colors.red[400],
),
padding: EdgeInsets.all(16),
),
alignment: Alignment.center,
transform: Matrix4.identity()
..rotateZ(15 * 3.1415927 / 180),
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Вопрос
Как скейлить компоненты?
Ответ
С помощью виджета Transform.
Пример
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
transform: scale(1.5);
}
Flutter
var container = Container( // gray box
child: Center(
child: Transform(
child: Container( // red box
child: Text(
"Lorem ipsum",
style: bold24Roboto,
textAlign: TextAlign.center,
),
decoration: BoxDecoration(
color: Colors.red[400],
),
padding: EdgeInsets.all(16),
),
alignment: Alignment.center,
transform: Matrix4.identity()
..scale(1.5),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Вопрос
Как применить градиент?
Ответ
С помощью класса BoxDecoration и его свойства gradient
.
Пример
Вертикальный линейный градиент
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
padding: 16px;
color: #ffffff;
background: linear-gradient(180deg, #ef5350, rgba(0, 0, 0, 0) 80%);
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red box
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: const Alignment(0.0, -1.0),
end: const Alignment(0.0, 0.6),
colors: <Color>[
const Color(0xffef5350),
const Color(0x00ef5350)
],
),
),
padding: EdgeInsets.all(16),
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Горизонтальный линейный градиент
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
padding: 16px;
color: #ffffff;
background: linear-gradient(90deg, #ef5350, rgba(0, 0, 0, 0) 80%);
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red box
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: const Alignment(-1.0, 0.0),
end: const Alignment(0.6, 0.0),
colors: <Color>[
const Color(0xffef5350),
const Color(0x00ef5350)
],
),
),
padding: EdgeInsets.all(16),
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Форма
Вопрос
Как скруглять углы?
Ответ
С помощью класса BoxDecoration и его свойства borderRadius
.
Пример
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* gray 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
border-radius: 8px;
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red circle
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
decoration: BoxDecoration(
color: Colors.red[400],
borderRadius: BorderRadius.all(
const Radius.circular(8),
),
),
padding: EdgeInsets.all(16),
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Вопрос
Как добавить тень?
Ответ
С помощью класса BoxShadow.
Дополнительная информация
BoxShadow используется в рамках свойства boxShadow
класса BoxDecoration.
Пример
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.8),
0 6px 20px rgba(0, 0, 0, 0.5);
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red box
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
decoration: BoxDecoration(
color: Colors.red[400],
boxShadow: [
BoxShadow (
color: const Color(0xcc000000),
offset: Offset(0, 2),
blurRadius: 4,
),
BoxShadow (
color: const Color(0x80000000),
offset: Offset(0, 6),
blurRadius: 20,
),
],
),
padding: EdgeInsets.all(16),
),
),
width: 320,
height: 240,
decoration: BoxDecoration(
color: Colors.grey[300],
),
margin: EdgeInsets.only(bottom: 16),
);
Вопрос
Как делать круглые и эллипсовидные формы?
Ответ
С помощью enum
-класса BoxShape.
Дополнительная информация
BoxShape используется в рамках свойства shape класса BoxDecoration.
Пример
HTML/CSS
<div class="greybox">
<div class="redcircle">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* gray 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redcircle {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
text-align: center;
width: 160px;
height: 160px;
border-radius: 50%;
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red circle
child: Text(
"Lorem ipsum",
style: bold24Roboto,
textAlign: TextAlign.center,
),
decoration: BoxDecoration(
color: Colors.red[400],
shape: BoxShape.circle,
),
padding: EdgeInsets.all(16),
width: 160,
height: 160,
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Текст
Вопрос
Как регулировать расстояние между текстом?
Ответ
С помощью класса TextStyle и его свойств letterSpacing
и wordSpacing
.
Пример
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
letter-spacing: 4px;
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red box
child: Text(
"Lorem ipsum",
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.w900,
letterSpacing: 4,
),
),
decoration: BoxDecoration(
color: Colors.red[400],
),
padding: EdgeInsets.all(16),
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Вопрос
Как форматировать часть текста?
Ответ
С помощью виджета RichText и класса TextSpan.
Пример
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem <em>ipsum</em>
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
}
.redbox em {
font: 300 48px Roboto;
font-style: italic;
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red box
child: RichText(
text: TextSpan(
style: bold24Roboto,
children: <TextSpan>[
TextSpan(text: "Lorem "),
TextSpan(
text: "ipsum",
style: TextStyle(
fontWeight: FontWeight.w300,
fontStyle: FontStyle.italic,
fontSize: 48,
),
),
],
),
),
decoration: BoxDecoration(
color: Colors.red[400],
),
padding: EdgeInsets.all(16),
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
Вопрос
Как ограничить показ длинного текста?
Ответ
С помощью совойств maxLines
и overflow
виджета Text.
Пример
HTML/CSS
<div class="greybox">
<div class="redbox">
Lorem ipsum dolor sit amet, consec etur
</div>
</div>
.greybox {
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 900 24px Roboto;
display: flex;
align-items: center;
justify-content: center;
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Flutter
var container = Container( // grey box
child: Center(
child: Container( // red box
child: Text(
"Lorem ipsum dolor sit amet, consec etur",
style: bold24Roboto,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
decoration: BoxDecoration(
color: Colors.red[400],
),
padding: EdgeInsets.all(16),
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
В конце декабря 2019 года, с выходом Flutter 1.12, поддержка веба перешла в стадию beta! И это отличная новость, означающая, что в недалёком будущем мы будем всё чаще встречать сайты, написанные на Flutter. Поэтому, если вы всё ещё в раздумьях, рекомендую попробовать этот фреймворк и надеюсь, что моя статья была полезной. А на сегодня у меня всё. Да не сломает Google ваш Chrome!
Автор: Дмитрий Васильев