diff --git a/example/lib/main.dart b/example/lib/main.dart index d24829ed..0ead8552 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -38,6 +38,11 @@ class PersistenBottomNavBarDemo extends StatelessWidget { Navigator.of(context).pushNamed("/interactive"), child: const Text("Show Interactive Example"), ), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () => Navigator.of(context).pushNamed("/redirect"), + child: const Text("Show Redirect Example"), + ), ], ), ), @@ -45,6 +50,7 @@ class PersistenBottomNavBarDemo extends StatelessWidget { routes: { "/minimal": (context) => const MinimalExample(), "/interactive": (context) => const InteractiveExample(), + "/redirect": (context) => RedirectExample(), }, ); } @@ -84,3 +90,59 @@ class MinimalExample extends StatelessWidget { ), ); } + +class RedirectExample extends StatelessWidget { + RedirectExample({super.key}); + + List _tabs() => [ + PersistentTabConfig( + screen: const MainScreen(), + item: ItemConfig( + icon: const Icon(Icons.home), + title: "Home", + ), + ), + PersistentTabConfig( + screen: const MainScreen(), + item: ItemConfig( + icon: const Icon(Icons.message), + title: "Messages", + ), + ), + PersistentTabConfig( + screen: const MainScreen(), + item: ItemConfig( + icon: const Icon(Icons.settings), + title: "Settings", + ), + ), + ]; + + final controller = PersistentTabController(); + + @override + Widget build(BuildContext context) => PersistentTabView( + controller: controller, + tabs: _tabs(), + navBarBuilder: (navBarConfig) => Style1BottomNavBar( + navBarConfig: navBarConfig, + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + controller.jumpToTab(2); + }, + child: const Text('Jump'), + ), + onRedirect: (index) async { + if (index == 2) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Intercept when jumping to $index'), + ), + ); + return true; + } + return null; + }, + ); +} diff --git a/example/pubspec.lock b/example/pubspec.lock index bca279bc..c046ecdc 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: async sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.11.0" boolean_selector: @@ -14,7 +14,7 @@ packages: description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" characters: @@ -22,7 +22,7 @@ packages: description: name: characters sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.0" clock: @@ -30,7 +30,7 @@ packages: description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" collection: @@ -38,7 +38,7 @@ packages: description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.18.0" cupertino_icons: @@ -46,7 +46,7 @@ packages: description: name: cupertino_icons sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.6" fake_async: @@ -54,7 +54,7 @@ packages: description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.1" flutter: @@ -66,10 +66,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 - url: "https://pub.dev" + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.1" + version: "3.0.2" flutter_test: dependency: "direct dev" description: flutter @@ -84,16 +84,16 @@ packages: dependency: "direct main" description: name: go_router - sha256: "466425a64508ca00983882f523400d9169365cb9b464e2e2419f3b6545ff9c51" - url: "https://pub.dev" + sha256: "9e0f7d1a3e7dc5010903e330fbc5497872c4c3cf6626381d69083cc1d5113c1e" + url: "https://pub.flutter-io.cn" source: hosted - version: "14.0.1" + version: "14.0.2" leak_tracker: dependency: transitive description: name: leak_tracker sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "10.0.0" leak_tracker_flutter_testing: @@ -101,7 +101,7 @@ packages: description: name: leak_tracker_flutter_testing sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.1" leak_tracker_testing: @@ -109,7 +109,7 @@ packages: description: name: leak_tracker_testing sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.1" lints: @@ -117,7 +117,7 @@ packages: description: name: lints sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.0" logging: @@ -125,7 +125,7 @@ packages: description: name: logging sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" matcher: @@ -133,7 +133,7 @@ packages: description: name: matcher sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.12.16+1" material_color_utilities: @@ -141,7 +141,7 @@ packages: description: name: material_color_utilities sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.8.0" meta: @@ -149,7 +149,7 @@ packages: description: name: meta sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.11.0" path: @@ -157,7 +157,7 @@ packages: description: name: path sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.9.0" persistent_bottom_nav_bar_v2: @@ -177,7 +177,7 @@ packages: description: name: source_span sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.10.0" stack_trace: @@ -185,7 +185,7 @@ packages: description: name: stack_trace sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.11.1" stream_channel: @@ -193,7 +193,7 @@ packages: description: name: stream_channel sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" string_scanner: @@ -201,7 +201,7 @@ packages: description: name: string_scanner sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" term_glyph: @@ -209,7 +209,7 @@ packages: description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.1" test_api: @@ -217,7 +217,7 @@ packages: description: name: test_api sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.6.1" vector_math: @@ -225,7 +225,7 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" vm_service: @@ -233,7 +233,7 @@ packages: description: name: vm_service sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "13.0.0" sdks: diff --git a/lib/components/persistent_tab_view.dart b/lib/components/persistent_tab_view.dart index ef3503f5..e350c9f2 100644 --- a/lib/components/persistent_tab_view.dart +++ b/lib/components/persistent_tab_view.dart @@ -40,6 +40,7 @@ class PersistentTabView extends StatefulWidget { this.drawerEdgeDragWidth, this.gestureNavigationEnabled = false, this.animatedTabBuilder, + this.onRedirect, }) : navigationShell = null; const PersistentTabView.router({ @@ -71,6 +72,7 @@ class PersistentTabView extends StatefulWidget { this.drawerEdgeDragWidth, this.gestureNavigationEnabled = false, this.animatedTabBuilder, + this.onRedirect, }) : screenTransitionAnimation = const ScreenTransitionAnimation(), controller = null; @@ -208,6 +210,10 @@ class PersistentTabView extends StatefulWidget { final StatefulNavigationShell? navigationShell; + /// If retrun `true`, you can't additionally swipe left/right to change the tab. + /// Defaults to `null`. + final Future Function(int index)? onRedirect; + @override State createState() => _PersistentTabViewState(); } @@ -235,7 +241,9 @@ class _PersistentTabViewState extends State { PersistentTabController( initialIndex: widget.navigationShell?.currentIndex ?? 0, ); - _controller.onIndexChanged = widget.onTabChanged; + _controller + ..onIndexChanged = widget.onTabChanged + ..onRedirect = widget.onRedirect; _contextList = List.filled(widget.tabs.length, null); diff --git a/lib/models/persistent_tab_controller.dart b/lib/models/persistent_tab_controller.dart index a42f4771..e86f0aa9 100644 --- a/lib/models/persistent_tab_controller.dart +++ b/lib/models/persistent_tab_controller.dart @@ -33,12 +33,18 @@ class PersistentTabController extends ChangeNotifier { GlobalKey scaffoldKey = GlobalKey(); final List _tabHistory = []; ValueChanged? onIndexChanged; + Future Function(int index)? onRedirect; - void _updateIndex(int value, [bool isUndo = false]) { + Future _updateIndex(int value, [bool isUndo = false]) async { assert(value >= 0, "Nav Bar item index cannot be less than 0"); if (_index == value) { return; } + + if (await onRedirect?.call(value) ?? false) { + return; + } + if (!isUndo) { if (_clearHistoryOnInitialIndex && value == _initialIndex) { _tabHistory.clear(); diff --git a/pubspec.lock b/pubspec.lock index fb9ed433..e3788a8a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: async sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.11.0" boolean_selector: @@ -14,7 +14,7 @@ packages: description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" characters: @@ -22,7 +22,7 @@ packages: description: name: characters sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.0" clock: @@ -30,7 +30,7 @@ packages: description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" collection: @@ -38,7 +38,7 @@ packages: description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.18.0" fake_async: @@ -46,7 +46,7 @@ packages: description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.1" flutter: @@ -58,10 +58,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 - url: "https://pub.dev" + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.1" + version: "3.0.2" flutter_test: dependency: "direct dev" description: flutter @@ -76,16 +76,16 @@ packages: dependency: "direct main" description: name: go_router - sha256: "7ecb2f391edbca5473db591b48555a8912dde60edd0fb3013bd6743033b2d3f8" - url: "https://pub.dev" + sha256: "9e0f7d1a3e7dc5010903e330fbc5497872c4c3cf6626381d69083cc1d5113c1e" + url: "https://pub.flutter-io.cn" source: hosted - version: "13.2.1" + version: "14.0.2" leak_tracker: dependency: transitive description: name: leak_tracker sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "10.0.0" leak_tracker_flutter_testing: @@ -93,7 +93,7 @@ packages: description: name: leak_tracker_flutter_testing sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.1" leak_tracker_testing: @@ -101,7 +101,7 @@ packages: description: name: leak_tracker_testing sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.1" lints: @@ -109,7 +109,7 @@ packages: description: name: lints sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.0" logging: @@ -117,7 +117,7 @@ packages: description: name: logging sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" matcher: @@ -125,7 +125,7 @@ packages: description: name: matcher sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.12.16+1" material_color_utilities: @@ -133,7 +133,7 @@ packages: description: name: material_color_utilities sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.8.0" meta: @@ -141,7 +141,7 @@ packages: description: name: meta sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.11.0" path: @@ -149,7 +149,7 @@ packages: description: name: path sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.9.0" sky_engine: @@ -162,7 +162,7 @@ packages: description: name: source_span sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.10.0" stack_trace: @@ -170,7 +170,7 @@ packages: description: name: stack_trace sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.11.1" stream_channel: @@ -178,7 +178,7 @@ packages: description: name: stream_channel sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" string_scanner: @@ -186,7 +186,7 @@ packages: description: name: string_scanner sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" term_glyph: @@ -194,7 +194,7 @@ packages: description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.1" test_api: @@ -202,7 +202,7 @@ packages: description: name: test_api sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.6.1" vector_math: @@ -210,7 +210,7 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" vm_service: @@ -218,7 +218,7 @@ packages: description: name: vm_service sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "13.0.0" sdks: