#flutter
#flutter
Вопрос:
Что у меня есть:
Dismissible(
key: Key(state.threads[index].toString()),
onDismissed: (direction) {
setState(() {
state.threads.removeAt(index);
});
},
);
Работает нормально. Я могу отклонять элементы, проводя пальцем влево. Однако я хотел бы подтвердить действие, и то, что я понял и прочитал, я должен использовать
confirmDismiss:
Однако, как новичок и с отсутствием примеров, плюс документация буквально ничего не объясняет для меня, что я понимаю. Как этого добиться?
Ответ №1:
В confirmDismiss
атрибуте вы можете вернуть AlertDialog()
(или любой другой тип диалогового окна, который вы предпочитаете), а затем перечислить возможные результаты (например, удалить и отменить) в кнопках и вернуть либо true
(удалить), либо false
(отмена), который затем определяет, должен ли элемент быть удален или должен остаться в списке.
Пример:
confirmDismiss: (DismissDirection direction) async {
return await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text("Confirm"),
content: const Text("Are you sure you wish to delete this item?"),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(true),
child: const Text("DELETE")
),
FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: const Text("CANCEL"),
),
],
);
},
);
},
Вы можете извлечь логику в метод, чтобы сделать код более читаемым.
Комментарии:
1. Получаем 2 ошибки: A) Эта функция имеет возвращаемый тип ‘Future<bool>’, но не заканчивается оператором return. Попробуйте добавить оператор return или изменить возвращаемый тип на ‘void’. Б) Значение локальной переменной ‘res’ не используется. Попробуйте удалить переменную или использовать ее. Пожалуйста, поделитесь своим предложением.
2. @Kamlesh попробуйте вернуть await ShowDialog, например: confirmDismiss: (направление отклонения) async { вернуть await ShowDialog(….); },
3. Вы на самом деле хотите вернуть Future<bool> из await вместо того, чтобы устанавливать для него значение res и ничего с ним не делать. возврат ожидает ShowDialog(….
4. Возможно, вам потребуется добавить —> return res; в конце перед закрывающей скобкой;
Ответ №2:
Вот пример из репозитория flutter.
Протестировано на версии flutter 1.12.
Future<bool> _showConfirmationDialog(BuildContext context, String action) {
return showDialog<bool>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Do you want to $action this item?'),
actions: <Widget>[
FlatButton(
child: const Text('Yes'),
onPressed: () {
Navigator.pop(context, true); // showDialog() returns true
},
),
FlatButton(
child: const Text('No'),
onPressed: () {
Navigator.pop(context, false); // showDialog() returns false
},
),
],
);
},
);
}
Добавить внутри Dismissible виджет:
confirmDismiss: (DismissDirection dismissDirection) async {
switch(dismissDirection) {
case DismissDirection.endToStart:
return await _showConfirmationDialog(context, 'archive') == true;
case DismissDirection.startToEnd:
return await _showConfirmationDialog(context, 'delete') == true;
case DismissDirection.horizontal:
case DismissDirection.vertical:
case DismissDirection.up:
case DismissDirection.down:
assert(false);
}
return false;
}
Ответ №3:
Я использовал приведенный ниже код в проекте, где я мог архивировать или удалять уведомления. @Yurij Kots ответ вместе с интерактивным примером flutter, найденным здесь Пример из документов Flutter: CookBook
Смотрите изображение. Если вы потянете вправо или влево, он покажет вам базовый ЗНАЧОК, который находится под элементом … сообщая вам, «что может произойти»!
ЧТОБЫ ПОСМОТРЕТЬ, КАК РАБОТАЕТ КОД: просто просмотрите весь приведенный ниже код в интерактивном примере кода ссылки.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
MyAppState createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
final items = List<String>.generate(20, (i) => "Item ${i 1} A B C D E... X Y Z");
String whatHappened;
@override
Widget build(BuildContext context) {
final title = 'Notification Items List';
return MaterialApp(
title: title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
key: Key(item),
onDismissed: (direction) {
setState(() {
items.removeAt(index);
});
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text("$item was $whatHappened")));
},
confirmDismiss: (DismissDirection dismissDirection) async {
switch(dismissDirection) {
case DismissDirection.endToStart:
whatHappened = 'ARCHIVED';
return await _showConfirmationDialog(context, 'Archive') == true;
case DismissDirection.startToEnd:
whatHappened = 'DELETED';
return await _showConfirmationDialog(context, 'Delete') == true;
case DismissDirection.horizontal:
case DismissDirection.vertical:
case DismissDirection.up:
case DismissDirection.down:
assert(false);
}
return false;
},
background: Container(
padding: EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerLeft,
child: Icon(Icons.cancel),
),
secondaryBackground: Container(
padding: EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.green,
alignment: Alignment.centerRight,
child: Icon(Icons.check),
),
child: ListTile(title: Text('$item')),
);
},
),
),
);
}
}
Future<bool> _showConfirmationDialog(BuildContext context, String action) {
return showDialog<bool>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Do you want to $action this item?'),
actions: <Widget>[
FlatButton(
child: const Text('Yes'),
onPressed: () {
Navigator.pop(context, true); // showDialog() returns true
},
),
FlatButton(
child: const Text('No'),
onPressed: () {
Navigator.pop(context, false); // showDialog() returns false
},
),
],
);
},
);
}
Комментарии:
1. @EmJeiEn запрашивает подтверждение отклонения, и вы отвечаете на совершенно разные вещи