Modale Dialoge
Einleitung
Nylo Website bietet ein Modal-System, das auf Bottom-Sheet-Modalen basiert.
Die Klasse BottomSheetModal bietet eine flexible API zur Anzeige von Inhalts-Overlays mit Aktionen, Kopfzeilen, Schliessen-Schaltflaechen und benutzerdefiniertem Styling.
Modale sind nuetzlich fuer:
- Bestaetigungsdialoge (z. B. Abmelden, Loeschen)
- Schnelle Eingabeformulare
- Aktionslisten mit mehreren Optionen
- Informations-Overlays
Ein Modal erstellen
Sie koennen ein neues Modal mit der Metro-CLI erstellen:
metro make:bottom_sheet_modal payment_options
Dies erstellt zwei Dinge:
- Ein Modal-Inhalts-Widget unter
lib/resources/widgets/bottom_sheet_modals/modals/payment_options_modal.dart:
import 'package:flutter/material.dart';
/// Payment Options Modal
///
/// Used in BottomSheetModal.showPaymentOptions()
class PaymentOptionsModal extends StatelessWidget {
const PaymentOptionsModal({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('PaymentOptionsModal').headingLarge(),
],
);
}
}
- Eine statische Methode, die Ihrer
BottomSheetModal-Klasse inlib/resources/widgets/bottom_sheet_modals/bottom_sheet_modals.darthinzugefuegt wird:
/// Show Payment Options modal
static Future<void> showPaymentOptions(BuildContext context) {
return displayModal(
context,
isScrollControlled: false,
child: const PaymentOptionsModal(),
);
}
Anschliessend koennen Sie das Modal von ueberall aufrufen:
BottomSheetModal.showPaymentOptions(context);
Wenn ein Modal mit demselben Namen bereits existiert, verwenden Sie das --force-Flag zum Ueberschreiben:
metro make:bottom_sheet_modal payment_options --force
Grundlegende Verwendung
Zeigen Sie ein Modal mit BottomSheetModal an:
BottomSheetModal.showLogout(context);
Ein Modal erstellen
Das empfohlene Muster ist die Erstellung einer BottomSheetModal-Klasse mit statischen Methoden fuer jeden Modal-Typ. Die Projektvorlage bietet diese Struktur:
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
class BottomSheetModal extends NyBaseModal {
static ModalShowFunction get displayModal => displayModal;
/// Show Logout modal
static Future<void> showLogout(
BuildContext context, {
Function()? onLogoutPressed,
Function()? onCancelPressed,
}) {
return displayModal(
context,
isScrollControlled: false,
child: const LogoutModal(),
actionsRow: [
Button.secondary(
text: "Logout",
onPressed: onLogoutPressed ?? () => routeToInitial(),
),
Button(
text: "Cancel",
onPressed: onCancelPressed ?? () => Navigator.pop(context),
),
],
);
}
}
Rufen Sie es von ueberall auf:
BottomSheetModal.showLogout(context);
// With custom callbacks
BottomSheetModal.showLogout(
context,
onLogoutPressed: () {
// Custom logout logic
},
onCancelPressed: () {
Navigator.pop(context);
},
);
BottomSheetModal
displayModal<T>() ist die Kernmethode zur Anzeige von Modalen.
Parameter
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
context |
BuildContext |
erforderlich | Build-Kontext fuer das Modal |
child |
Widget |
erforderlich | Haupt-Inhalts-Widget |
actionsRow |
List<Widget> |
[] |
Aktions-Widgets in einer horizontalen Reihe |
actionsColumn |
List<Widget> |
[] |
Aktions-Widgets vertikal angeordnet |
height |
double? |
null | Feste Hoehe fuer das Modal |
header |
Widget? |
null | Kopfzeilen-Widget oben |
useSafeArea |
bool |
true |
Inhalt in SafeArea einbetten |
isScrollControlled |
bool |
false |
Modal scrollbar machen |
showCloseButton |
bool |
false |
X-Schliessen-Schaltflaeche anzeigen |
headerPadding |
EdgeInsets? |
null | Abstand bei vorhandener Kopfzeile |
backgroundColor |
Color? |
null | Hintergrundfarbe des Modals |
showHandle |
bool |
true |
Ziehgriff oben anzeigen |
closeButtonColor |
Color? |
null | Hintergrundfarbe der Schliessen-Schaltflaeche |
closeButtonIconColor |
Color? |
null | Symbolfarbe der Schliessen-Schaltflaeche |
modalDecoration |
BoxDecoration? |
null | Benutzerdefinierte Dekoration fuer den Modal-Container |
handleColor |
Color? |
null | Farbe des Ziehgriffs |
Aktionen
Aktionen sind Schaltflaechen, die am unteren Rand des Modals angezeigt werden.
Zeilenaktionen werden nebeneinander platziert, wobei jede den gleichen Platz einnimmt:
displayModal(
context,
child: Text("Are you sure?"),
actionsRow: [
ElevatedButton(
onPressed: () => Navigator.pop(context, true),
child: Text("Yes"),
),
TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text("No"),
),
],
);
Spaltenaktionen werden vertikal gestapelt:
displayModal(
context,
child: Text("Choose an option"),
actionsColumn: [
ElevatedButton(
onPressed: () => Navigator.pop(context, true),
child: Text("Yes"),
),
TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text("No"),
),
],
);
Kopfzeile
Fuegen Sie eine Kopfzeile hinzu, die ueber dem Hauptinhalt steht:
displayModal(
context,
header: Container(
padding: EdgeInsets.all(16),
color: Colors.blue,
child: Text(
"Modal Title",
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
child: Text("Modal content goes here"),
);
Schliessen-Schaltflaeche
Zeigen Sie eine Schliessen-Schaltflaeche in der oberen rechten Ecke an:
displayModal(
context,
showCloseButton: true,
closeButtonColor: Colors.grey.shade200,
closeButtonIconColor: Colors.black,
child: Padding(
padding: EdgeInsets.all(24),
child: Text("Content with close button"),
),
);
Benutzerdefinierte Dekoration
Passen Sie das Erscheinungsbild des Modal-Containers an:
displayModal(
context,
backgroundColor: Colors.transparent,
modalDecoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
boxShadow: [
BoxShadow(color: Colors.black26, blurRadius: 10),
],
),
handleColor: Colors.grey.shade400,
child: Text("Custom styled modal"),
);
BottomModalSheetStyle
BottomModalSheetStyle konfiguriert das Erscheinungsbild von Bottom-Sheet-Modalen, die von Formular-Pickern und anderen Komponenten verwendet werden:
BottomModalSheetStyle(
backgroundColor: NyColor(light: Colors.white, dark: Colors.grey.shade900),
barrierColor: NyColor(light: Colors.black54, dark: Colors.black87),
useRootNavigator: false,
titleStyle: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
itemStyle: TextStyle(fontSize: 16),
clearButtonStyle: TextStyle(color: Colors.red),
)
| Eigenschaft | Typ | Beschreibung |
|---|---|---|
backgroundColor |
NyColor? |
Hintergrundfarbe des Modals |
barrierColor |
NyColor? |
Farbe des Overlays hinter dem Modal |
useRootNavigator |
bool |
Root-Navigator verwenden (Standard: false) |
routeSettings |
RouteSettings? |
Routeneinstellungen fuer das Modal |
titleStyle |
TextStyle? |
Stil fuer den Titeltext |
itemStyle |
TextStyle? |
Stil fuer Listenelementtext |
clearButtonStyle |
TextStyle? |
Stil fuer den Loeschen-Schaltflaechentext |
Beispiele
Bestaetigungsmodal
static Future<bool?> showConfirm(
BuildContext context, {
required String message,
}) {
return displayModal<bool>(
context,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Text(message, textAlign: TextAlign.center),
),
actionsRow: [
ElevatedButton(
onPressed: () => Navigator.pop(context, true),
child: Text("Confirm"),
),
TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text("Cancel"),
),
],
);
}
// Usage
bool? confirmed = await BottomSheetModal.showConfirm(
context,
message: "Delete this item?",
);
if (confirmed == true) {
// delete the item
}
Scrollbares Inhaltsmodal
displayModal(
context,
isScrollControlled: true,
height: MediaQuery.of(context).size.height * 0.8,
showCloseButton: true,
header: Padding(
padding: EdgeInsets.all(16),
child: Text("Terms of Service", style: TextStyle(fontSize: 20)),
),
child: SingleChildScrollView(
child: Text(longTermsText),
),
);
Aktionsliste
displayModal(
context,
showHandle: true,
child: Text("Share via", style: TextStyle(fontSize: 18)),
actionsColumn: [
ListTile(
leading: Icon(Icons.email),
title: Text("Email"),
onTap: () {
Navigator.pop(context);
shareViaEmail();
},
),
ListTile(
leading: Icon(Icons.message),
title: Text("Message"),
onTap: () {
Navigator.pop(context);
shareViaMessage();
},
),
ListTile(
leading: Icon(Icons.copy),
title: Text("Copy Link"),
onTap: () {
Navigator.pop(context);
copyLink();
},
),
],
);