Оповещения используются для предоставления некоторой информации / подтверждения или получения подтверждения от пользователя. В зависимости от требований можно соответствующим образом настроить оповещение.
Flutter предоставляет виджет для отображения предупреждений пользователю. Для его настройки необходимо определить заголовок предупреждения, подробное сообщение и действия.
Для платформы iOS будет использоваться CupertinoAlertDialog, который делает то же самое на устройствах iPhone.
По этой причине всякий раз, когда требуется оповещение, все детали необходимо определять повторно. Это приводит к тому, что один и тот же код неоднократно появляется в проекте.
Но не бойтесь! Я объясню, как мы можем написать один код AlertDialog, который мы можем использовать всякий раз, когда нам нужно отображать предупреждения в проекте.
Первый шаг
Мы начнем с создания нового проекта флаттера с помощью Android Studio, дадим ему имя и определим путь, по которому он должен быть сохранен в системе.
После успешного создания проекта вы увидите автоматически сгенерированный код в файле main.dart. Замените весь автоматически сгенерированный код из файла main.dart следующей единственной строкой и оператором импорта:
import ‘package:flutter/material.dart’; import ‘my_app.dart’; void main() => runApp(MyApp());
Пока не обращайте внимания на ошибку.
Теперь создайте новый файл dart, назовите его «my_app.dart» в папке «projects lib».
Вставьте приведенный ниже код во вновь созданный файл my_app.dart.
import ‘package:flutter/material.dart’; class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: ‘Flutter Demo’, theme: ThemeData( primarySwatch: Colors.blue, ), home: HomeScreen(), ); } }
Этот код создаст виджет MyApp Stateless и вернет приложение Material. Этот виджет MyApp будет корнем нашего приложения.
Теперь нам нужно добавить новый виджет в качестве дома для виджета MyApp. Давайте создадим его и добавим приведенный ниже код виджета HomeScreen в тот же файл my_app.dart после класса MyApp:
class HomeScreen extends StatefulWidget { @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { return Container( color: Colors.blueGrey, ); } }
После запуска этого сценария все ошибки должны исчезнуть, а если вы запустите приложение, вы увидите пустой экран сине-серого цвета.
Затем поместим одну кнопку в центр этого экрана, при нажатии на которую будет отображаться предупреждение.
Замените метод build для HomeScreenState приведенным ниже кодом:
@override Widget build(BuildContext context) { return Container( color: Colors.blueGrey, child: Center(child: RaisedButton( child: Text(‘Show Alert’), onPressed: () { print(‘Show Alert’); }, ), ), ); }
После выполнения горячей перезагрузки приложение отобразит кнопку в центре экрана с заголовком «Показать предупреждение».
Теперь создайте новый файл дротика и назовите его «dl_alert.dart». Этот файл будет содержать фактический код предупреждения, который будет использоваться во всем приложении.
Вверху только что созданного файла dl_alert.dart добавьте следующие операторы импорта:
import ‘dart:io’; import ‘package:flutter/cupertino.dart’; import ‘package:flutter/material.dart’;
Теперь добавьте это в файл dl_alert.dart:
typedef AlertAction<T> = void Function(T index);
Создание класса
После этого создайте новый класс с именем «DLAlert» и добавьте к нему несколько свойств:
class DLAlert { DLAlert({ @required this.cancelTitle, this.alertTitle = ‘Alert’, this.alertDetailMessage = ‘’, @required this.alertActionTitles, @required this.onAlertAction}); String alertTitle; String alertDetailMessage; String cancelTitle; List<String> alertActionTitles; AlertAction<int> onAlertAction; }
Теперь мы создали «класс DLAlert» с некоторыми переменными и конструктором и инициализировали его переменные.
cancelTitle, alertttitle, alertDetailMessage - все это объекты String, которые могут содержать некоторые сообщения для пользователя.
Мы также создали «alertActionTitles», который будет содержать все заголовки предупреждений и других действий. В результате в предупреждении будет кнопка действий alertActionTitles.length + 1 (как в 1 отменить действие).
Каждый раз, когда нажимается кнопка действия, он отправляет вызов обратно в класс, откуда он был вызван.
Создание функции
Теперь мы создадим функцию, которая создаст оповещение и представит его пользователю.
Добавьте приведенную ниже функцию в конец класса DLAlert:
void show(BuildContext context) { List<Widget> actions = <Widget>[]; //Customize the cancel button as per the requirement Widget actionButton = FlatButton( child: Text(cancelTitle), onPressed: () { Navigator.pop(context); }, ); actions.add(actionButton); for(int i = 0; i < alertActionTitles.length; i++) { Widget actionButton = FlatButton( child: Text(alertActionTitles[i]), onPressed: () { Navigator.pop(context); onAlertAction(i); }, ); actions.add(actionButton); } }
Обратите внимание, что команда ‘show ()’ создает список для FlatButton, который будет использоваться для действия alertDialog.
В зависимости от платформы, на которой нам нужно отображать диалоговое окно с предупреждением, добавьте в класс DLAlert следующий метод:
Widget _getAlertDialog(List<Widget> actions) { if (Platform.isIOS) return CupertinoAlertDialog( title: Text(alertTitle), content: Text(alertDetailMessage), actions: actions ); else return AlertDialog( title: Text(alertTitle), content: Text(alertDetailMessage), actions: actions ); }
В зависимости от платформы эта функция вернет alertDialog.
Теперь мы обработали код alertDialog для конкретной платформы, давайте вернемся, чтобы показать метод, и обновим его следующим образом:
void show(BuildContext context) { List<Widget> actions = <Widget>[]; //Customize the cancel button as per the requirement Widget actionButton = FlatButton( child: Text(cancelTitle), onPressed: () { Navigator.pop(context); }, ); actions.add(actionButton); for(int i = 0; i < alertActionTitles.length; i++) { Widget actionButton = FlatButton( child: Text(alertActionTitles[i]), onPressed: () { Navigator.pop(context); onAlertAction(i); }, ); actions.add(actionButton); } // show the dialog showDialog( barrierDismissible: false, context: context, builder: (BuildContext context) { return _getAlertDialog(actions); }, ); }
После добавления всех методов ваш файл dl_alert.dart должен выглядеть так:
import ‘dart:io’; import ‘package:flutter/cupertino.dart’; import ‘package:flutter/material.dart’; typedef AlertAction<T> = void Function(T index); class DLAlert { DLAlert({ @required this.cancelTitle, this.alertTitle = ‘Alert’, this.alertDetailMessage = ‘’, @required this.alertActionTitles, @required this.onAlertAction}); String alertTitle; String alertDetailMessage; String cancelTitle; List<String> alertActionTitles; AlertAction<int> onAlertAction; void show(BuildContext context) { List<Widget> actions = <Widget>[]; //Customize the cancel button as per the requirement Widget actionButton = FlatButton( child: Text(cancelTitle), onPressed: () { Navigator.pop(context); }, ); actions.add(actionButton); for(int i = 0; i < alertActionTitles.length; i++) { Widget actionButton = FlatButton( child: Text(alertActionTitles[i]), onPressed: () { Navigator.pop(context); onAlertAction(i); }, ); actions.add(actionButton); } // show the dialog showDialog( barrierDismissible: false, context: context, builder: (BuildContext context) { return _getAlertDialog(actions); }, ); } Widget _getAlertDialog(List<Widget> actions) { if (Platform.isIOS) return CupertinoAlertDialog( title: Text(alertTitle), content: Text(alertDetailMessage), actions: actions ); else return AlertDialog( title: Text(alertTitle), content: Text(alertDetailMessage), actions: actions ); } }
Затем давайте попробуем показать диалоговое окно, используя этот многоразовый код из нашего файла my_app.dart.
Отображение диалогового окна предупреждения
Сначала импортируйте только что созданный файл dl_alert.dart. Замените центральный виджет, который мы создали ранее, следующим кодом:
Center(child: RaisedButton( child: Text(‘Show Alert’), onPressed: () { print(‘Show Alert’); List<String> alertTitles = <String>[‘Ok’]; DLAlert( cancelTitle: ‘Cancel’, alertTitle: ‘Alert Title’, alertDetailMessage: ‘Alert Detail’, alertActionTitles: alertTitles, onAlertAction: (int selectedActionIndex){ print(‘${alertTitles[selectedActionIndex]} action performed’); }).show(context); }, ),
Ваш класс HomeScreen и _HomeScreenState должны выглядеть так:
class HomeScreen extends StatefulWidget { @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { return Container( color: Colors.blueGrey, child: Center(child: RaisedButton( child: Text(‘Show Alert’), onPressed: () { List<String> alertTitles = <String>[‘Ok’]; DLAlert(cancelTitle: ‘Cancel’, alertTitle: ‘Alert Title’, alertDetailMessage: ‘Alert Detail’, alertActionTitles:alertTitles, onAlertAction: (int selectedActionIndex){ print(‘${alertTitles[selectedActionIndex]} action performed’); } ).show(context); }, ), ), ); } }
Наконец, запустите приложение. Теперь вы должны увидеть экран ниже на своих устройствах iOS и Android:
На iPhone будет отображаться CupertinoAlertDialog, а на устройстве Android - собственный AlertDialog Android, как показано на соседнем изображении.
При нажатии кнопки «Показать предупреждение» в центре экрана отобразится диалоговое окно (alertDialog) с параметрами «отменить» и «ОК» на обеих платформах.
Нажатие на «Ok» приведет к вызову onAlertAction
, и индекс этого действия (нажатие) будет передан вместе с функцией обратного вызова. Событие можно обработать соответствующим образом.
Спасибо за внимание! Надеюсь, это было полезно.
Удачного кодирования :)
DLT Labs является товарным знаком DLT Global, Inc. Flutter ™ является товарным знаком Google LLC, и его использование здесь не означает одобрения или принадлежности.
Автор - Сухаил Шабир, DLT Labs ™
Об авторе: Сухайль - увлеченный разработчик мобильных приложений, который работал над iOS и технологиями Flutter. Он участвовал во всех основных мобильных приложениях DLT Labs.