🔙 Swipe to navigate back and admire beautifully morphing widgets.
SwipeablePageRoute is a specialized CupertinoPageRoute that allows your users to go back by swiping anywhere on the current page. Use it instead of MaterialPageRoute or CupertinoPageRoute :
Navigator .of (context).push (SwipeablePageRoute (
builder: (BuildContext context) => MyPageContent (),
));
If your page contains horizontally scrollable content, you can limit SwipeablePageRoute to only react on drags from the start (left in LTR, right in RTL) screen edge — just like CupertinoPageRoute :
Navigator .of (context).push (SwipeablePageRoute (
canOnlySwipeFromEdge: true ,
builder: (BuildContext context) => MyHorizontallyScrollablePageContent (),
));
You can get the SwipeablePageRoute wrapping your current page using context.getSwipeablePageRoute<T>().
To use swipeable pages with a PageTransitionsTheme , use SwipeablePageTransitionsBuilder .
⚠️ SwipeablePageTransitionsBuilder must be set for TargetPlatform.iOS .
For all other platforms, you can decide whether you want to use it.
This is because PageTransitionsTheme uses the builder for iOS whenever a pop gesture is in progress.
Usage with Go Router
To use swipeable pages with Flutter's Go Router , use SwipeablePage and the pageBuilder parameter in GoRoute instead of builder:
GoRoute (
builder: (context, state) => const MyScreen (),
)
GoRoute (
pageBuilder: (context, state) => SwipeablePage (
builder: (context) => MyScreen (),
),
)
As you can see in the demo above, there's a beautiful animation happening to the app bar. That's a MorphingAppBar !
You can construct MorphingAppBar (corresponds to AppBar) and MorphingSliverAppBar (corresponds to SliverAppBar) just like the originals:
MorphingAppBar (
backgroundColor: Colors .green,
title: Text ('My Page' ),
actions: [
IconButton (
key: ValueKey ('play' ),
icon: Icon (Icons .play_arrow),
onPressed: () {},
),
IconButton (
key: ValueKey ('favorite' ),
icon: Icon (Icons .favorite),
onPressed: () {},
),
PopupMenuButton <void >(
key: ValueKey ('overflow' ),
itemBuilder: (context) => [
PopupMenuItem <void >(child: Text ('Overflow action 1' )),
PopupMenuItem <void >(child: Text ('Overflow action 2' )),
],
),
],
bottom: TabBar (tabs: [
Tab (text: 'Tab 1' ),
Tab (text: 'Tab 2' ),
Tab (text: 'Tab 3' ),
]),
)
Both MorphingAppBar s internally use Hero s, so if you're not navigating directly inside a MaterialApp, you have to add a HeroController to your Navigator:
Navigator (
observers: [HeroController ()],
onGenerateRoute:
)
To animate additions, removals, and constants in your AppBars actions, we compare them using Widget.canUpdate(Widget old, Widget new) . It compares Widgets based on their type and key, so it's recommended to give every action Widget a key (that you reuse across pages) for correct animations.