✨flutter_easyloading: простой в использованииFlutterПлагин, включающий 23 вида анимационных эффектов загрузки, отображение индикатора выполнения, отображение тостов. Реализация Pure Flutter, поддержка iOS, Android.
✨адрес с открытым исходным кодом:GitHub.com/ Look Oh Look Yellow/ Волосы…
предисловие
Flutter
даGoogle
Набор кроссплатформенных программ с открытым исходным кодом, запущенных в 2017 году.UI
каркас, который может быстроiOS
,Android
а такжеWeb
Создавайте высококачественные нативные пользовательские интерфейсы на платформе.Flutter
С момента своего выпуска можно сказать, что он очень популярен и привлек большое количествоApp
нативные разработчики,Web
Именно потому, что разработчики вложили в свое вооружение одно за другимFlutter
Nova Field - это кроссплатформенная, в целом, его экология еще не идеальна, я считаю, что студенты, привыкли к родной разработке, колесо, безусловно, не нашел своего рода главы о чувстве на руке Левина. Например, эта статья о упоминании, какFlutter
Простая и удобная презентация в приложенииToast
илиLoading
Упаковать?
проводить исследования
pubЯ нашел еще несколько отличных плагинов:
-
FlutterToast: Этот плагин должен быть у многих новичков
Flutter
Это зависит от натива, но проблемы на уровне пользовательского интерфейса лучше всего решать на стороне Flutter, что удобно для последующего обслуживания, а также может уменьшить проблемы с совместимостью; -
flutter_oktoast: чистый
Flutter
Сквозная реализация, легко звонить. но отсутствуетloading
, Дисплей прогресса, вы можете настроить вашу реализацию;
试用过后,发现这些插件都或多或少不能满足我们的产品需求,于是便结合自己产品的需求来造了这么个轮子,也希望可以帮到有需要的同学们。 Предварительный просмотр эффекта:
выполнить
реализация showDialog
Давайте посмотрим, как мы реализовали всплывающее окно на ранней стадии.showDialog
, часть исходного кода выглядит следующим образом:
Future<T> showDialog<T>({
@required BuildContext context,
bool barrierDismissible = true,
@Deprecated(
'Instead of using the "child" argument, return the child from a closure '
'provided to the "builder" argument. This will ensure that the BuildContext '
'is appropriate for widgets built in the dialog. '
'This feature was deprecated after v0.2.3.'
)
Widget child,
WidgetBuilder builder,
bool useRootNavigator = true,
})
Есть обязательный параметрcontext
, должно быть, был в контакте сFlutter
Студенты, которые развивались в течение определенного периода времени, будут правы.BuildContext
понимать. Проще говоряBuildContext
это построитьWidget
Контекст приложения в , этоFlutter
важные части.BuildContext
Появляется только в двух местах:
-
StatelessWidget.build
В методе: создатьStatelessWidget
изbuild
метод -
State
StatefulWidget
изState
объектbuild
State
Переменная-член
СвязанныйBuildContext
showDialog
Реализовать всплывающую операцию окна, то вопрос, который мы считаем, так это то, как все удобно получить и быстроBuildContext
, чтобы реализовать всплывающее окно. Если одноклассник использует егоshowDialog
Таким образом, я полагаю, вы найдете, доступ в любое местоBuildContext
Это не так просто и создает много ненужного кода.
Итак, нам просто придется использовать этот крайне недружественный подход?
Конечно нет, продолжайте читать.
Введение в трепетание EasyLoading
Flutter EasyLoading
Flutter
23Добрыйloading
Toast
экспонат. чистыйFlutter
iOS
,Android
.先简单看下如何使用Flutter EasyLoading
.
Установить
Добавьте следующий код в свой проектpubspec.yaml
документ:
dependencies:
flutter_easyloading: ^1.1.0 // 请使用最新版
импорт
import 'package:flutter_easyloading/flutter_easyloading.dart';
как использовать
Во-первых, используйтеFlutterEasyLoading
Компонент обертывает ваш компонент приложения:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
/// 子组件通常为 [MaterialApp] 或者 [CupertinoApp].
/// 这样做是为了确保 loading 组件能覆盖在其他组件之上.
return FlutterEasyLoading(
child: MaterialApp(
title: 'Flutter EasyLoading',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter EasyLoading'),
),
);
}
}
Тогда, пожалуйста, наслаждайтесь:
EasyLoading.show(status: 'loading...');
EasyLoading.showProgress(0.3, status: 'downloading...');
EasyLoading.showSuccess('Great Success!');
EasyLoading.showError('Failed with Error');
EasyLoading.showInfo('Useful Information.');
EasyLoading.dismiss();
Пользовательский стиль
Во-первых, давайте посмотрим наFlutter EasyLoading
В настоящее время поддерживаются пользовательские свойства:
/// loading的样式, 默认[EasyLoadingStyle.dark].
EasyLoadingStyle loadingStyle;
/// loading的指示器类型, 默认[EasyLoadingIndicatorType.fadingCircle].
EasyLoadingIndicatorType indicatorType;
/// loading的遮罩类型, 默认[EasyLoadingMaskType.none].
EasyLoadingMaskType maskType;
/// 文本的对齐方式 , 默认[TextAlign.center].
TextAlign textAlign;
/// loading内容区域的内边距.
EdgeInsets contentPadding;
/// 文本的内边距.
EdgeInsets textPadding;
/// 指示器的大小, 默认40.0.
double indicatorSize;
/// loading的圆角大小, 默认5.0.
double radius;
/// 文本大小, 默认15.0.
double fontSize;
/// 进度条指示器的宽度, 默认2.0.
double progressWidth;
/// [showSuccess] [showError] [showInfo]的展示时间, 默认2000ms.
Duration displayDuration;
/// 文本的颜色, 仅对[EasyLoadingStyle.custom]有效.
Color textColor;
/// 指示器的颜色, 仅对[EasyLoadingStyle.custom]有效.
Color indicatorColor;
/// 进度条指示器的颜色, 仅对[EasyLoadingStyle.custom]有效.
Color progressColor;
/// loading的背景色, 仅对[EasyLoadingStyle.custom]有效.
Color backgroundColor;
/// 遮罩的背景色, 仅对[EasyLoadingMaskType.custom]有效.
Color maskColor;
/// 当loading展示的时候,是否允许用户操作.
bool userInteractions;
/// 展示成功状态的自定义组件
Widget successWidget;
/// 展示失败状态的自定义组件
Widget errorWidget;
/// 展示信息状态的自定义组件
Widget infoWidget;
потому чтоEasyLoading
является глобальным синглтоном, поэтому мы можем настроить его стиль в любом месте:
EasyLoading.instance
..displayDuration = const Duration(milliseconds: 2000)
..indicatorType = EasyLoadingIndicatorType.fadingCircle
..loadingStyle = EasyLoadingStyle.dark
..indicatorSize = 45.0
..radius = 10.0
..backgroundColor = Colors.green
..indicatorColor = Colors.yellow
..textColor = Colors.yellow
..maskColor = Colors.blue.withOpacity(0.5);
Дополнительные типы анимации индикатора для просмотраflutter_spinkit showcase
можно увидеть,Flutter EasyLoading
Интеграция и довольно проста в использовании, и имеет множество пользовательских стилей, вы всегда будете довольны.
Flutter EasyLoading
Код.
Flutter EasyLoading
-
Overlay
,OverlayEntry
-
CustomPaint
а такжеCanvas
Реализовать круговую зачистку прогресса
Overlay, OverlayEntry реализуют глобальное всплывающее окно
Первый взгляд на официальномOverlay
описание:
/// A [Stack] of entries that can be managed independently.
///
/// Overlays let independent child widgets "float" visual elements on top of
/// other widgets by inserting them into the overlay's [Stack]. The overlay lets
/// each of these widgets manage their participation in the overlay using
/// [OverlayEntry] objects.
///
/// Although you can create an [Overlay] directly, it's most common to use the
/// overlay created by the [Navigator] in a [WidgetsApp] or a [MaterialApp]. The
/// navigator uses its overlay to manage the visual appearance of its routes.
///
/// See also:
///
/// * [OverlayEntry].
/// * [OverlayState].
/// * [WidgetsApp].
/// * [MaterialApp].
class Overlay extends StatefulWidget {}
То есть,Overlay
ЯвляетсяStack
изWidget
,могуOverlayEntry
вставить вOverlay
в, сделать независимымchild
Окно нависает над другимWidget
Над. Используя эту функцию, мы можем использоватьOverlay
БудуMaterialApp
илиCupertinoApp
loading
Flutter
Только в присутствииMaterialApp
илиCupertinoApp
компонент корневого узла. (Примечание: практика здесь относится кflutter_oktoastплагин, спасибо)
Кроме того, цель этого может также решить другую основную проблему:context
Кэшируется в памяти, все последующие вызовы предоставлять не нужноcontext
. Реализация заключается в следующем:
@override
Widget build(BuildContext context) {
return Directionality(
child: Overlay(
initialEntries: [
OverlayEntry(
builder: (BuildContext _context) {
// 缓存 context
EasyLoading.instance.context = _context;
// 这里的child必须是MaterialApp或CupertinoApp
return widget.child;
},
),
],
),
textDirection: widget.textDirection,
);
}
// 创建OverlayEntry
OverlayEntry _overlayEntry = OverlayEntry(
builder: (BuildContext context) => LoadingContainer(
key: _key,
status: status,
indicator: w,
animation: _animation,
),
);
// 将OverlayEntry插入到Overlay中
// 通过Overlay.of()我们可以获取到App根节点的Overlay
Overlay.of(_getInstance().context).insert(_overlayEntry);
// 调用OverlayEntry自身的remove()方法,从所在的Overlay中移除自己
_overlayEntry.remove();
Overlay
,OverlayEntry
Их очень просто использовать и понимать, и мы можем использовать их в других сценариях использования, например, в подобныхPopupWindow
эффект всплывающего окна, глобальная настройкаDialog
всплывающие окна и т.д. Пока мы используем его гибко, мы можем достичь многих желаемых эффектов.
CustomPaint
а такжеCanvas
Реализовать круговой рисунок индикатора выполнения
почти всеUI
Система обеспечит самостоятельную покраскуUI
интерфейс, который обычно предоставляет часть2D
холстCanvas
,Canvas
Внутренне инкапсулирует некоторый базовый рисунокAPI
, Мы можемCanvas
绘制各种自定义图形。 существуетFlutter
CustomPaint
CustomPainter
Давайте сначала посмотримCustomPaint
Конструктор:
const CustomPaint({
Key key,
this.painter,
this.foregroundPainter,
this.size = Size.zero,
this.isComplex = false,
this.willChange = false,
Widget child,
})
- painter: фоновая кисть, которая будет отображаться за дочерними узлами;
- foregroundPainter: рисование переднего плана, которое будет отображаться перед дочерними узлами
- размер: когда
child
дляnull
Когда от имени размера по умолчанию область рисования, если естьchild
затем игнорируйте этот параметр, размер холстаchild
размер. Если естьchild
Но если вы хотите указать холст определенного размера, вы можете использоватьSizeBox
пакетCustomPaint
выполнить. - isComplex: сложный ли рисунок, если да,
Flutter
Некоторые стратегии кэширования применяются для уменьшения накладных расходов на повторный рендеринг. - willChange: и
isComplex
При совместном использовании, когда кэширование включено, это свойство указывает, изменится ли рисунок в следующем кадре.
Как видите, нам нужно предоставить кисти переднего плана или фона при рисовании, и обе они могут быть предоставлены одновременно. Наши кисти должны наследоватьCustomPainter
мы реализуем реальную логику рисования в классе кисти.
Далее посмотрим как пройтиCustomPainter
Нарисуйте круговой индикатор выполнения:
class _CirclePainter extends CustomPainter {
final Color color;
final double value;
final double width;
_CirclePainter({
@required this.color,
@required this.value,
@required this.width,
});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = color
..strokeWidth = width
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawArc(
Offset.zero & size,
-math.pi / 2,
math.pi * 2 * value,
false,
paint,
);
}
@override
bool shouldRepaint(_CirclePainter oldDelegate) => value != oldDelegate.value;
}
Сверху мы можем видеть это,CustomPainter
Виртуальная функция определена вpaint
:
void paint(Canvas canvas, Size size);
- Холст: Холст, включая различные методы рендеринга, такие как
drawLine(画线)
,drawRect(画矩形)
,drawCircle(画圆)
Ждать
Теперь, когда у нас есть холст, нам нужна кисть.Flutter
при условииPaint
класс для реализации кистей. И вы можете настроить различные свойства кисти, такие как толщина, цвет, стиль и т. д., например:
final paint = Paint()
..color = color // 颜色
..strokeWidth = width // 宽度
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
Наконец, нам просто нужно использоватьdrawArc
Метод рисует дугу:
canvas.drawArc(
Offset.zero & size,
-math.pi / 2,
math.pi * 2 * value,
false,
paint,
);
На этом мы закончили рисование индикатора выполнения. Кроме того, нам также необходимо обратить внимание на проблему производительности рисования. К счастью, класс предоставляет переопределениеshouldRepaint
метод, этот метод определяет, когда холст будет перерисован, что весьма эффективно для повышения производительности рисования в сложном рисовании.
@override
bool shouldRepaint(_CirclePainter oldDelegate) => value != oldDelegate.value;
Эпилог
без сомнений,Flutter
Будущее светлое, и может быть еще много проблем, но я верю, что больше людей захотят сопровождатьFlutter
一起成长。 Ждать с нетерпениемFlutter
Flutter EasyLoading
Flutter EasyLoading
Для вашей помощи.