Этот раздел поможет вам глубже понять «холодные» знания о шрифтах и отрисовке текста в процессе разработки с использованием Flutter. Это позволит вам лучше понять и запомнить важные моменты, связанные с отрисовкой шрифтов в Flutter.
В конце концов, таких материалов слишком мало.
Давайте начнем с простого примера отображения текста, как показано ниже:
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Container(
color: Colors.lime,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
child: Container(
height: 200,
alignment: Alignment.center,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: new Text(
"H",
style: TextStyle(
fontSize: 100,
),
),
),
Container(
height: 100,
width: 100,
color: Colors.red,
)
],
),
),
),
),
);
}
Для ответа на этот вопрос мы добавили синий фон контейнеру, содержащему текст, а также красный квадрат размером 100x100 для сравнения:```dart @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Container( color: Colors.lime, alignment: Alignment.center, child: Container( alignment: Alignment.center, child: Container( height: 200, alignment: Alignment.center, child: new Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( color: Colors.blue, child: new Text( "H", style: TextStyle( fontSize: 100, ), ), ), Container( height: 100, width: 100, color: Colors.red, ) ], ), ), ), ), ); }
### ОписаниеНа следующем скриншоте можно видеть, что буква H имеет верхний и нижний отступы. Размер синего контейнера превышает 100 пикселей, но сам черный символ H находится внутри красного квадратика размером 100x100 пикселей.

Фактически, синий контейнер представляет собой высоту строки (line height). В `TextStyle` есть параметр `height`, который влияет на высоту строки.
По умолчанию значение параметра `height` равно `null`. Когда его установите в значение `1`, высота строки становится равной ширине символов:

Что такое параметр `height`? По документации, если параметр `height` установлен, то высота строки будет равна произведению значения `height` на значение `fontSize`.
На следующем скриншоте показана сравнительная высота строк при значении `height` как `null` и `1`.

Кроме того, на этом скриншоте также показано положение базовой линии относительно символов. Это объясняет, почему символ H с `fontSize` 100 не заполняет полностью высоту синего контейнера.
При значении `height` равном 1, символ H располагается над базовой линией, которая предназначена для других символов, таких как g и j. На следующем скриншоте показан пример использования символа g вместе с включенным отображением базовой линии в режиме отладки Flutter.

Пример использования символа `g` демонстрирует соответствие ожидаемому результату. Приведённый ниже код показывает, что происходит, когда мы устанавливаем высоту (`height`) равной **2**, а также добавляем контейнер с высотой **200** пикселей и фиолетовым фоном. В результате можно заметить, что синий блок полностью заполняет фиолетовый прямоугольник, так как текст с размером шрифта **100** после умножения на **x2** имеет высоту **200**.
```dart
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Container(
color: Colors.lime,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
child: Container(
height: 200,
color: Colors.purple,
alignment: Alignment.center,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.blue,
child: new Text(
"Hg",
style: TextStyle(
fontSize: 100,
height: 2,
),
),
),
Container(
height: 100,
width: 100,
color: Colors.red,
)
],
),
),
),
),
);
}
}
Однако здесь текст "Hg" смещен вниз, причины этого смещения будут объяснены далее, а также будет проведен новый сравнительный анализ.Наконец, приведенная ниже диаграмма демонстрирует сравнение высоты текста при различных значениях параметра
height
вTextStyle
, предоставляемое официальной документацией.
Представим, что вернемся к ранее упомянутому значению по умолчанию для шрифтов — мере. Как же эта мера строится? Ответ заключается в использовании StrutStyle
.
В приведенном ниже коде мы добавляем StrutStyle
к предыдущему коду:
forceStrutHeight
на значение true
, поскольку именно это свойство позволяет принудительно переопределить значение height
для Text
;height
в StrutStyle
на значение 1, таким образом, значение height
в TextStyle
, равное 2, становится бесполезным.@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Container(
color: Colors.lime,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
child: Container(
height: 200,
color: Colors.purple,
alignment: Alignment.center,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.blue,
child: new Text(
"Hg",
style: TextStyle(
fontSize: 100,
height: 2,
),
strutStyle: StrutStyle(
forceStrutHeight: true,
fontSize: 100,
height: 1
),
),
),
],
),
),
),
),
);
}
Приведенный ниже текст представляет собой перевод исходного текста с сохранением структуры и формата:
Результат представлен ниже на рисунке, хотя значение height
в TextStyle
равно 2, отображение происходит согласно значению height
в StrutStyle
, равному 1.
Затем, просмотрев документацию по параметру height
в StrutStyle
, можно заметить, что эффект этого параметра всё ещё зависит от множителя размера шрифта (fontSize
). Однако здесь добавлено дополнительное пояснение к параметру fontSize
: ascent + descent = fontSize
. Где:
ascent
— это часть над базовой линией;
descent
— это часть под базовой линией;
а их совместное действие представлено на следующем рисунке:
В Flutter параметры
ascent
иdescent
нельзя установить отдельно через код.
Кроме того, значение параметра fontSize
в StrutStyle
и TextStyle
имеет различное влияние: когда мы устанавливаем значение параметра fontSize
в StrutStyle
равным 50, а значение параметра fontSize
в TextStyle
остаётся равным 100, как показано на следующем рисунке, можно заметить, что размер чёрного текста не меняется, а синий участок становится размером 50.
Некоторые могут спросить, зачем тогда нужен параметр fontSize
в StrutStyle
?
При таких условиях, если поместить текст "Hg\nHg"
в виде двухстрочного текста, можно заметить, что строки накладываются друг на друга после переноса, поэтому параметр fontSize
в StrutStyle
также влияет на высоту строки.
Кроме того, в StrutStyle
есть ещё один параметр, который также влияет на высоту строки, это параметр leading
.Как показано на следующем рисунке, добавление параметра leading
позволяет полностью контролировать высоту строки в Flutter. По умолчанию значение параметра leading
равно null
, его эффект также является множителем размера шрифта (fontSize
) и распределяется поровну сверху и снизу.
Поэтому, как показано в приведённом ниже коде, при значении параметра fontSize
в StrutStyle
равном 100, значении height
равном 1 и значении leading
равном 1, можно видеть, что размер параметра leading
увеличивает синий участок до 200, тем самым высота синего участка снова совпадает с высотой фиолетового участка. При этом содержимое теперь центрировано по сравнению с предыдущими примерами с буквой "H".
---
``` @override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Container(
color: Colors.lime,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
child: Container(
height: 200,
color: Colors.purple,
alignment: Alignment.center,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.blue,
child: new Text(
"Hg",
style: TextStyle(
fontSize: 100,
height: 2,
),
strutStyle: StrutStyle(
forceStrutHeight: true,
fontSize: 100,
height: 1,
leading: 1
),
),
),
Container(
height: 100,
width: 100,
color: Colors.red,
)
],
),
)
),
),
);
}> Поскольку `leading` распределяется равномерно между верхней и нижней частями строки, а `height` увеличивает размер строки в соответствии с её высотой и глубиной, то есть `ascent` значительно превышает `descent`, при значении `height` равном 2, текстовое поле будет смещено вниз.

### Три. backgroundColor
На данном этапе вы должны иметь базовое понимание текстовых размеров, метрик и высоты строк в Flutter. Далее рассмотрим свойство `backgroundColor` в `TextStyle`.
> Введение этого свойства позволяет сделать сравнение с предыдущими материалами и развеять некоторые заблуждения.
Как показано ниже, значение `fontSize` в `StrutStyle` равно **100**, а `height` равно **1**. По нашим ранее данным, голубое пространство должно было бы совпадать по размеру с красной квадратной областью.
Затем мы установили `backgroundColor` в `TextStyle` как прозрачно-зелёный цвет. Результат представлен на следующем рисунке, где видно, что область `backgroundColor` превышает границы `StrutStyle` и отображается как **по умолчанию метрика шрифта**.
--- @override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Container(
color: Colors.lime,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
child: Container(
height: 200,
color: Colors.purple,
alignment: Alignment.center,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.blue,
child: new Text(
"Hg",
style: TextStyle(
fontSize: 100,
backgroundColor: Colors.green.withOpacity(0.7),
),
strutStyle: StrutStyle(
forceStrutHeight: true,
fontSize: 100,
height: 1,
),
),
),
Container(
height: 100,
width: 100,
color: Colors.red,
)
],
),
),
),
),
);
}
```
Это интересно? На самом деле это демонстрирует, что метрика шрифта всегда была по умолчанию `ascent + descent = fontSize`. Мы можем изменять высоту строки с помощью свойства `height` в `TextStyle` или `StrutStyle`, но фактический размер шрифта (`fontSize`) остаётся неизменным.
Если заменить входной текст на `"H\ng"`, как показано ниже, можно получить ещё более интересный эффект.

### Четвёртый раздел: TextBaseline
И последнее, рассмотрим свойство `TextBaseline` в `TextStyle`, которое часто вызывает недопонимание.
Свойство `TextBaseline` имеет два значения: `alphabetic` и `ideographic`. Чтобы лучше объяснить их действие, мы используем `CustomPaint`, чтобы отобразить различные позиции базовой линии, как показано ниже.
``````markdown
@override
виджет build(BuildContext контекст) {
return Scaffold(
backgroundColor: Цвета.чёрный,
тело: Container(
цвет: Цвета.лимо,
выравнивание: Alignment.center,
ребёнок: Container(
выравнивание: Alignment.center,
ребёнок: Container(
высота: 200,
ширина: 400,
цвет: Цвета.фиолетовый,
ребёнок: CustomPaint(
painter: Текст2Пейnter(),
),
)
)
)
);
}
```Ниже приведены текстовые описания, пояснения, комментарии и инструкции, а также сообщения об ошибках, предупреждения и пользовательские инструкции:---
На следующем рисунке показана синяя линия, которая представляет собой базовую линию (baseline). Благодаря визуальному эффекту можно легко заметить, где должны располагаться тексты при использовании различных значений базовой линии.

Однако фактическое значение базовой линии не оказывает прямого влияния на способ выравнивания текста в объекте `TextStyle`. По умолчанию Flutter использует выравнивание по алфавитной базовой линии (`TextBaseline.alphabetic`). На следующем рисунке представлено описание этого вопроса от официальных представителей проекта.

> Это объясняет необходимость использования `CustomPaint`, так как стандартный компонент `Text` не позволяет достичь желаемого эффекта.Примером может служить следующий код, где, несмотря на использование значения `ideographic` для свойства `textBaseline` в компонентах `Row` и `Text`, достигнуть желаемого выравнивания не удается.
```markdown
@Override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Container(
color: Colors.lime,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
child: Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaselineideographic,
mainAxisSize: MainAxisSize.max,
children: [
Text(
'我是中文',
style: TextStyle(
fontSize: 55,
textBaseline: TextBaselineideographic,
),
),
Spacer(),
Text('123y56',
style: TextStyle(
fontSize: 55,
textBaseline: TextBaselineideographic,
)),
])),
),
);
}
Даже если значение
mainAxisAlignment
установлено какcenter
, текст всё равно может выглядеть неравномерно выровненным.
С тех пор как были представлены "холодные" знания о шрифтах в Flutter, неизвестно, увеличилось ли количество ваших бесполезных знаний?
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )