showFPersistentSheet function
- @useResult
- required BuildContext context,
- required FLayout side,
- required Widget builder(
- BuildContext context,
- FPersistentSheetController controller
- FPersistentSheetStyle style()?,
- double? mainAxisMaxRatio = 9 / 16,
- BoxConstraints constraints = const BoxConstraints(),
- bool draggable = true,
- Offset? anchorPoint,
- bool useSafeArea = false,
- bool resizeToAvoidBottomInset = true,
- bool keepAliveOffstage = false,
- VoidCallback? onClosing,
- Key? key,
Shows a persistent sheet that appears above the current widget. It should have a FSheets or FScaffold ancestor.
The returned FPersistentSheetController should always be disposed after use. Not doing so can lead to the sheets accumulating over time, which can negatively impact performance.
A closely related widget is a modal sheet which prevents the user from interacting with the rest of the app.
context is used to look up the Navigator and FSheetStyle for the sheet. It is only used when the method is
called. Its corresponding widget can be safely removed from the tree before the sheet is closed.
style defaults to FSheetStyle from the closest FTheme ancestor.
mainAxisMaxRatio represents the main axis's max constraint ratio for the sheet, depending on side.
Defaults to 9 / 16. The main axis is the width if side is FLayout.ltr or FLayout.rtl, and the height if side
is FLayout.ttb or FLayout.btt. Consider setting mainAxisMaxRatio to null if this sheet has a scrollable child,
i.e. ListView, along the main axis, to have the sheet be draggable.
resizeToAvoidBottomInset determines whether the sheet should avoid the system's bottom view inset, typically the
keyboard, by shifting the entire sheet upwards. Defaults to true.
anchorPoint is used to pick the closest sub-screen.
keepAliveOffstage determines whether the sheet should be kept alive even when it is offstage. Setting it to true
retains the sheet's state even when it is not visible. Defaults to false. Keeping multiple sheets alive even when
offstage can negatively impact performance.
onClosing is called when the sheet begins to close.
key is used to identify the sheet. If a key is not provided, a random key will be generated. All sheets in a
FScaffold/FSheets must have unique keys.
Contract
Throws FlutterError if:
- the
contextdoes not contain a FSheets or FScaffold ancestor. - a sheet with the same
keyalready exists.
CLI
To generate and customize this widget's style:
dart run forui style create sheet
See:
- https://forui.dev/docs/overlay/persistent-sheet for working examples.
- showFSheet for showing a sheet in a modal that prevents the user from interacting with the rest of the app.
- FSheetStyle for customizing a switch's appearance.
- DraggableScrollableSheet, creates a bottom sheet that grows and then becomes scrollable once it reaches its maximum size.
Implementation
@useResult
FPersistentSheetController showFPersistentSheet({
required BuildContext context,
required FLayout side,
required Widget Function(BuildContext context, FPersistentSheetController controller) builder,
FPersistentSheetStyle Function(FPersistentSheetStyle)? style,
double? mainAxisMaxRatio = 9 / 16,
BoxConstraints constraints = const BoxConstraints(),
bool draggable = true,
Offset? anchorPoint,
bool useSafeArea = false,
bool resizeToAvoidBottomInset = true,
bool keepAliveOffstage = false,
VoidCallback? onClosing,
Key? key,
}) {
final state = context.findAncestorStateOfType<FSheetsState>();
if (state == null) {
throw FlutterError.fromParts([
ErrorSummary('showFSheet(...) called with a context that does not contain a FSheets/FScaffold.'),
ErrorDescription(
'No FSheets/FScaffold ancestor could be found starting from the context that was passed to FSheets/FScaffold.of(). '
'This usually happens when the context provided is from the same StatefulWidget as that whose build function '
'actually creates the FSheets/FScaffold widget being sought.',
),
ErrorHint(
'There are several ways to avoid this problem. The simplest is to use a Builder to get a '
'context that is "under" the FSheets/FScaffold.',
),
context.describeElement('The context used was'),
]);
}
key ??= ValueKey(Random().nextInt(2147483647));
final sheetStyle = style?.call(context.theme.persistentSheetStyle) ?? context.theme.persistentSheetStyle;
final controller = FPersistentSheetController._(
vsync: state,
style: sheetStyle,
key: key,
keepAliveOffstage: keepAliveOffstage,
setState: (function) {
if (state.mounted) {
// ignore: invalid_use_of_protected_member
state.setState(function);
}
},
onDispose: () => state._remove(key!),
);
try {
state._add(
controller,
Sheet(
controller: controller._controller,
animation: null,
style: sheetStyle,
side: side,
mainAxisMaxRatio: mainAxisMaxRatio,
constraints: constraints,
draggable: draggable,
anchorPoint: anchorPoint,
useSafeArea: useSafeArea,
resizeToAvoidBottomInset: resizeToAvoidBottomInset,
builder: (context) => builder(context, controller),
onChange: null,
onClosing: onClosing,
),
);
} catch (_) {
controller.dispose();
rethrow;
}
controller.show();
return controller;
}