swipe_back 0.0.2
swipe_back: ^0.0.2 copied to clipboard
iOS-style full screen back swipe gesture for Flutter. Enables swiping from anywhere on the screen to navigate back, not just the left edge.
example/lib/main.dart
import 'package:flutter/cupertino.dart' hide CupertinoPageRoute;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:swipe_back/swipe_back.dart';
void main() {
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
),
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Swipe Back',
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.light,
scaffoldBackgroundColor: const Color(0xFFF2F2F7),
primaryColor: const Color(0xFF007AFF),
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFFF2F2F7),
elevation: 0,
scrolledUnderElevation: 0,
iconTheme: IconThemeData(color: Color(0xFF007AFF)),
titleTextStyle: TextStyle(
color: Colors.black,
fontSize: 17,
fontWeight: FontWeight.w600,
letterSpacing: -0.4,
),
),
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.iOS: SwipeBackPageTransitionsBuilder(),
TargetPlatform.android: SwipeBackPageTransitionsBuilder(),
TargetPlatform.macOS: SwipeBackPageTransitionsBuilder(),
TargetPlatform.windows: SwipeBackPageTransitionsBuilder(),
},
),
),
darkTheme: ThemeData(
brightness: Brightness.dark,
scaffoldBackgroundColor: const Color(0xFF000000),
primaryColor: const Color(0xFF0A84FF),
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF000000),
elevation: 0,
scrolledUnderElevation: 0,
iconTheme: IconThemeData(color: Color(0xFF0A84FF)),
titleTextStyle: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w600,
letterSpacing: -0.4,
),
),
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.iOS: SwipeBackPageTransitionsBuilder(),
TargetPlatform.android: SwipeBackPageTransitionsBuilder(),
TargetPlatform.macOS: SwipeBackPageTransitionsBuilder(),
TargetPlatform.windows: SwipeBackPageTransitionsBuilder(),
},
),
),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: 120,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
titlePadding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
title: Text(
'Settings',
style: TextStyle(
color: isDark ? Colors.white : Colors.black,
fontWeight: FontWeight.w700,
letterSpacing: -0.5,
),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'SWIPE BACK DEMO',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w400,
color: isDark ? Colors.white54 : Colors.black54,
),
),
const SizedBox(height: 8),
Container(
decoration: BoxDecoration(
color: isDark ? const Color(0xFF1C1C1E) : Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
_SettingsTile(
icon: CupertinoIcons.profile_circled,
iconColor: Colors.blue,
title: 'Account Profiles',
onTap: () => Navigator.push(
context,
CupertinoPageRoute(
builder: (context) =>
const DetailScreen(title: 'Account Profiles'),
title: 'Profiles',
),
),
),
_Divider(),
_SettingsTile(
icon: CupertinoIcons.settings,
iconColor: Colors.grey,
title: 'General Settings',
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const DetailScreen(title: 'General Settings'),
),
),
),
_Divider(),
_SettingsTile(
icon: CupertinoIcons.hand_draw,
iconColor: Colors.purple,
title: 'Gesture Playground',
onTap: () => Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => const DetailScreen(
title: 'Gesture Playground'),
title: 'Gestures',
),
),
),
],
),
),
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'This example demonstrates the SwipeBackPageTransitionsBuilder allowing you to swipe back from anywhere on the screen.',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w400,
color: isDark ? Colors.white54 : Colors.black54,
),
),
),
],
),
),
),
],
),
);
}
}
class _SettingsTile extends StatelessWidget {
final IconData icon;
final Color iconColor;
final String title;
final VoidCallback onTap;
const _SettingsTile({
required this.icon,
required this.iconColor,
required this.title,
required this.onTap,
});
@override
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(10),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: iconColor,
borderRadius: BorderRadius.circular(8),
),
child: Icon(icon, color: Colors.white, size: 18),
),
const SizedBox(width: 16),
Expanded(
child: Text(
title,
style: const TextStyle(
fontSize: 17,
letterSpacing: -0.4,
fontWeight: FontWeight.w400,
),
),
),
Icon(
CupertinoIcons.chevron_right,
color: isDark ? const Color(0xFF3A3A3C) : const Color(0xFFC7C7CC),
size: 18,
),
],
),
),
);
}
}
class _Divider extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Padding(
padding: const EdgeInsets.only(left: 54.0),
child: Divider(
height: 1,
thickness: 0.5,
color: isDark ? const Color(0xFF38383A) : const Color(0xFFC6C6C8),
),
);
}
}
class DetailScreen extends StatelessWidget {
final String title;
const DetailScreen({super.key, required this.title});
@override
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: isDark ? const Color(0xFF1C1C1E) : Colors.white,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(13),
blurRadius: 20,
offset: const Offset(0, 10),
),
],
),
child: Icon(
CupertinoIcons.hand_draw_fill,
size: 64,
color: Theme.of(context).primaryColor,
),
),
const SizedBox(height: 32),
const Text(
'Swipe Right',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.w700,
letterSpacing: -0.5,
),
),
const SizedBox(height: 12),
Text(
'You can swipe from anywhere on this screen to go back to the previous screen, not just the left edge.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: isDark ? Colors.white54 : Colors.black54,
height: 1.4,
),
),
],
),
),
),
);
}
}