Как восьмую статью серии, эта статья рассказывает о полезных советах при разработке с использованием Flutter, чтобы помочь вам избежать распространённых ошибок и трудностей. Вся статья представляет собой концентрированный набор практических рекомендаций, который дополняется практическими примерами.
Иногда вы задаете свойство ellipsis для компонента Text
, но эффект от этого не проявляется, вместо этого вы видите предупреждение "overflowed", как показано на следующем рисунке слева.
На самом деле большинство случаев связано с тем, что внутренний метод RenderParagraph
проверяет условие final bool didOverflowWidth = size.width < textSize.width;
. Когда значения size.width
и textSize.width
равны, это приводит к тому, что свойство ellipsis не применяется.
Поэтому вам следует ограничить размер компонента Text
путём помещения его в контейнер типа Container
или использование сочетания Row
и Expanded
для установки границ для вашего Text
. Если вы не знаете, какой размер выбрать, можно воспользоваться LayoutBuilder
.
GlobalKey
для получения объекта BuildContext
компонента. Мы также говорили ранее, что BuildContext
реализуется через Element
, а Element
хранит RenderObject
. Таким образом, когда мы получаем RenderObject
, на самом деле мы получаем RenderBox
. Используя RenderBox
, мы можем получить размер и положение компонента:showSizes() {
RenderBox renderBoxRed = fileListKey.currentContext.findRenderObject();
print(renderBoxRed.size);
}
``````markdown
### 3\. Получение высоты области состояния и безопасной разметки
Если вы изучили исходный код `MaterialApp`, вы заметили бы, что внутри него находится `WidgetsApp`, который содержит `MediaQuery`. Те, кто знаком с этим компонентом, могут использовать `MediaQuery.of(context).size` для получения размера экрана.
`MediaQuery` является типом `InheritedWidget`, который имеет параметр `MediaQueryData`, который устанавливается следующим образом. Изучив исходный код, мы узнали, что обычно значение поля `top` параметра `padding` в `MediaQueryData` равно высоте области состояния. Поэтому мы можем получить высоту области состояния через `MediaQueryData.fromWindow(WidgetsBinding.instance.window).padding.top`, а иногда может потребоваться рассмотреть параметр `viewInsets`.

Что касается высоты компонента `AppBar`, то по умолчанию она равна `Size.fromHeight(kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0))`, где `kToolbarHeight` — это константное значение. Конечно, вы можете использовать реализацию `PreferredSizeWidget` для кастомизации `AppBar`.
Вы также можете заметить, что иногда при размещении элементов происходит смещение расчёта от области состояния вверх. В этом случае вам следует использовать `SafeArea` для обёртки. Причины этого можно найти в исходном коде, где используется `MediaQueryData`.
```### 4. Установка цвета области состояния и цвета значков
Просто используйте свойство `brightness` компонента `AppBar` или `ThemeData` для установки цвета области состояния.
Однако если вы не хотите использовать `AppBar`, вы можете обернуть его в `AnnotatedRegion<SystemUiOverlayStyle>`, чтобы установить стиль области состояния. Через `SystemUiOverlayStyle` вы сможете быстро настроить внешний вид области состояния и нижней навигационной панели.
Кроме того, вы можете использовать `SystemChrome.setSystemUIOverlayStyle` для установки стилей, но только если вы не используете `AppBar`. **Важно отметить, что все изменения стиля области состояния являются глобальными**, поэтому если вы установите стиль на странице A, он будет применяться автоматически на странице B, если там нет других настроек или использования `AppBar`.
### 5. Системное масштабирование шрифтов
Современные телефоны обычно предоставляют возможность масштабировать шрифты, что усложняет адаптивность приложений. Поэтому большинство разработчиков предпочитает запрещать масштабирование шрифтов в своих приложениях.
Масштабирование шрифтов в Flutter связано с параметром `textScaleFactor` объекта `MediaQueryData`. Поэтому вы можете использовать следующий код для установки шрифтов так, чтобы они не масштабировались:
```dart
MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window).copyWith(textScaleFactor: 1),
child: new Container(),
);
```### 6. Отступы и поля
При использовании контейнера `Container` часто используют параметры `margin` и `padding`. Мы уже говорили ранее, что `Container` является просто обёрткой различных типов размещения, где внутренние параметры `margin` и `padding` реализуются через `Padding`. Однако `Padding` не поддерживает отрицательные значения, поэтому рекомендуется использовать `Transform`, если вам нужны такие значения.
```dart
Transform(
transform: Matrix4.translationValues(10, -10, 0),
child: Container(),
);
В повседневной разработке мы обычно используем два способа создания закругленных углов:
BoxDecoration
, который является частью интерфейса Decoration
.ClipRRect
.Класс BoxDecoration
обычно применяется в компонентах DecoratedBox
и Container
. Этот подход обычно приводит к непосредственному отрисовыванию канваса для текущего компонента, что позволяет создать закругленные углы для фона, но это не влияет на его потомков (children
). Это значит, что если ваш потомок — это изображение или имеет свой фон, эффект закругленных углов может быть потерян.
С другой стороны, компонент ClipRRect
действительно влияет на потомков. Это можно понять из следующего источника кода рендера объекта.
TabBarView
вместе с KeepAlive
, то я рекомендую вам использовать PageView
. На данный момент, до версии 1.2, при использовании KeepAlive
, переход между двумя и более страницами через TabBarView
приводит к вызову методов dispose
и initState
для каждой страницы. Хотя внутри TabBarView
используется комбинация PageView
и TabBar
.Вы можете использовать комбинацию PageView
и TabBar
напрямую, а также использовать _pageController.jumpTo(MediaQuery.of(context).size.width * index)
для перехода между страницами, чтобы избежать некоторых проблем. Однако это будет означать потерю анимационного эффекта. В действительности, TabBarView
представляет собой просто обёртку над PageView
и TabBar
.
Кроме того, существует второй подход, который использует PageStorageKey
для хранения состояния страниц. Однако, поскольку этот метод основан на "сохранении и восстановлении значений", каждый раз при переходе между страницами будут вызываться методы dispose
и initState
.
return Scaffold(
key: PageStorageKey<String>('your_value'),
);
В Flutter ленивая загрузка данных может быть легко реализована с помощью FutureBuilder
или StreamBuilder
. Эти компоненты позволяют асинхронно получать данные через future
или stream
, после чего данные могут быть загружены с помощью AsyncSnapshot.data
. Подробнее о потоках и асинхронных операциях можно узнать позже.### 10. Возврат на главный экран Android устройства
Официальный плагин Flutter android_intent предлагает простое решение для возврата на главный экран устройства:
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter/material.dart';
import 'package:android_intent/android_intent.dart';
void main() {
runApp(MaterialApp(home: Home()));
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
onPressed: () async {
final intent = AndroidIntent(action: 'android.intent.action.MAIN');
await intent.start();
},
child: Text('Возврат на главный экран')));
}
}
Future<bool> _диалогВыходИзПриложения(BuildContext context) async {
if (Platform.isAndroid) {
AndroidIntent intent = AndroidIntent(
action: 'android.intent.action.MAIN',
category: "android.intent.category.HOME",
);
await intent.launch();
}
return Future.value(false);
}
return WillPopScope(
onWillPop: () {
return _диалогВыходИзПриложения(context);
},
child: xxx);
Наконец, восьмая статья завершена! (///▽///)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )