Оповещения используются для предоставления некоторой информации / подтверждения или получения подтверждения от пользователя. В зависимости от требований можно соответствующим образом настроить оповещение.

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.