iOS style fullscreen nested navigation #67
-
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 5 replies
-
Can you explain in more detail how your code did not work? By the way, you don't even need to use the // Use this instead of the NavigationSheet in your pseudocode.
DraggableSheet(
child: Navigator(...),
); If your sheet has both scrollable and non-scrollable widgets, you may want to use the ScrollableSheet(
child: SheetDraggable(
child: Navigator(...),
),
); |
Beta Was this translation helpful? Give feedback.
-
Thank you for reply this! I will try later and response |
Beta Was this translation helpful? Give feedback.
-
Sorry for the delay, and sorry for this silly question, I modified "cupertino_modal_sheet.dart" like this but not worked, I think I use it in a wrong way: import 'package:flutter/cupertino.dart';
import 'package:smooth_sheets/smooth_sheets.dart';
void main() {
runApp(const _CupertinoModalSheetExample());
}
class _CupertinoModalSheetExample extends StatelessWidget {
const _CupertinoModalSheetExample();
@override
Widget build(BuildContext context) {
return const CupertinoApp(
home: _ExampleHome(),
);
}
}
class _ExampleHome extends StatelessWidget {
const _ExampleHome();
@override
Widget build(BuildContext context) {
return CupertinoStackedTransition(
cornerRadius: Tween(begin: 0.0, end: 16.0),
child: CupertinoPageScaffold(
child: Center(
child: CupertinoButton.filled(
onPressed: () => _showModalSheet(context, isFullScreen: false),
child: const Text('Show Modal Sheet'),
),
),
),
);
}
}
void _showModalSheet(BuildContext context, {required bool isFullScreen}) {
Route modalRoute = CupertinoModalSheetRoute(
transitionCurve: Curves.easeInOut,
builder: (context) => ScrollableSheet(
child: SheetDraggable(
child: Navigator(
observers: [NavigationSheetTransitionObserver()],
onGenerateInitialRoutes: (navigator, initialRoute) {
return [
CupertinoModalSheetRoute(
builder: (context) {
return const _FullScreenSheet();
},
),
];
},
),
),
),
);
Navigator.push(context, modalRoute);
}
class _FullScreenSheet extends StatelessWidget {
const _FullScreenSheet();
@override
Widget build(BuildContext context) {
return const DraggableSheet(
child: _SheetContent(),
);
}
}
class _SheetContent extends StatelessWidget {
const _SheetContent();
@override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: const ShapeDecoration(
color: CupertinoColors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(16),
),
),
),
child: SizedBox.expand(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CupertinoButton.filled(
onPressed: () {
DefaultSheetController.maybeOf(context)?.animateTo(const Extent.proportional(1));
_showModalSheet(context, isFullScreen: true);
},
child: const Text('Stack'),
),
const SizedBox(height: 16),
CupertinoButton(
onPressed: () => Navigator.pop(context),
child: const Text('Close'),
),
],
),
),
),
);
}
} I think I should't use 'DraggableSheet' or 'ScrollableSheet' in this case, assuming there are 3 pages, Page A->Page B->Page C What I'm trying to do is that Page A is CupertinoModalSheetRoute, Page B is also CupertinoModalSheetRoute, but Page C is like CupertinoPageRoute which can be "navigated in Page B", just like the video, could you please provide a simple code example? |
Beta Was this translation helpful? Give feedback.
-
Here is my solution for the sheet in the video you posted. Codeimport 'package:flutter/material.dart';
import 'package:smooth_sheets/smooth_sheets.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CupertinoStackedTransition(
child: Scaffold(
body: Center(
child: Builder(
builder: (context) {
return FilledButton(
onPressed: () {
showFullscreenNestedNavigationSheet(context);
},
child: const Text('Show Sheet'),
);
},
),
),
),
),
);
}
}
void showFullscreenNestedNavigationSheet(BuildContext context) {
final route = CupertinoModalSheetRoute(
builder: (context) {
return const SheetDismissible(
child: FullscreenNestedNavigationSheet(),
);
},
);
Navigator.push(context, route);
}
final transitionObserver = NavigationSheetTransitionObserver();
class FullscreenNestedNavigationSheet extends StatelessWidget {
const FullscreenNestedNavigationSheet({super.key});
@override
Widget build(BuildContext context) {
final sheetContent = ColoredBox(
color: Theme.of(context).colorScheme.surface,
// Create a nested navigator
child: Navigator(
observers: [transitionObserver],
onGenerateInitialRoutes: (navigator, initialRoute) => [
// Or use a DraggableNavigationSheetRoute.
ScrollableNavigationSheetRoute(
builder: (_) => const ExamplePage(depth: 0),
),
],
),
);
return NavigationSheet(
transitionObserver: transitionObserver,
child: sheetContent,
);
}
}
/// A page shown in the NavigationSheet.
class ExamplePage extends StatelessWidget {
const ExamplePage({
super.key,
required this.depth,
});
final int depth;
@override
Widget build(BuildContext context) {
// Do not wrap this Scaffold with a sheet such as ScrollableSheet
// since it is already wrapped in a NavigationSheet and the sheets
// can't be nested within each other.
return Scaffold(
appBar: AppBar(
title: Text('Depth: $depth'),
),
body: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
onTap: () {
Navigator.of(context).push(
// Or use a DraggableNavigationSheetRoute.
ScrollableNavigationSheetRoute(
builder: (context) => ExamplePage(depth: depth + 1),
),
);
},
);
},
),
);
}
} ResultRocketSim_Recording_iPhone_15_6.1_2024-03-05_22.48.04.mp4
For this situation, the widget tree of your app will probably look like the following:
The PageA can be a |
Beta Was this translation helpful? Give feedback.
Here is my solution for the sheet in the video you posted.
Code