diff --git a/example/lib/customs/pickers/directory_file_asset_picker.dart b/example/lib/customs/pickers/directory_file_asset_picker.dart index 535cb316..1b2654d7 100644 --- a/example/lib/customs/pickers/directory_file_asset_picker.dart +++ b/example/lib/customs/pickers/directory_file_asset_picker.dart @@ -171,26 +171,10 @@ class _DirectoryFileAssetPickerState extends State { themeData: AssetPicker.themeData(themeColor), ), ); - final PageRouteBuilder> pageRoute = - PageRouteBuilder>( - pageBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - ) { - return viewer; - }, - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return FadeTransition(opacity: animation, child: child); - }, - ); final List? result = - await Navigator.maybeOf(context)?.push>(pageRoute); + await Navigator.maybeOf(context)?.push>( + AssetPickerViewerPageRoute(builder: (context) => viewer), + ); if (result != null && result != fileList) { fileList ..clear() @@ -384,27 +368,19 @@ class FileAssetPickerBuilder int? index, File currentAsset, ) async { + final Widget viewer = AssetPickerViewer( + builder: FileAssetPickerViewerBuilderDelegate( + currentIndex: index ?? provider.selectedAssets.indexOf(currentAsset), + previewAssets: provider.selectedAssets, + provider: FileAssetPickerViewerProvider(provider.selectedAssets), + themeData: AssetPicker.themeData(themeColor), + selectedAssets: provider.selectedAssets, + selectorProvider: provider, + ), + ); final List? result = await Navigator.maybeOf(context)?.push?>( - PageRouteBuilder>( - pageBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - ) { - return AssetPickerViewer( - builder: FileAssetPickerViewerBuilderDelegate( - currentIndex: - index ?? provider.selectedAssets.indexOf(currentAsset), - previewAssets: provider.selectedAssets, - provider: FileAssetPickerViewerProvider(provider.selectedAssets), - themeData: AssetPicker.themeData(themeColor), - selectedAssets: provider.selectedAssets, - selectorProvider: provider, - ), - ); - }, - ), + AssetPickerViewerPageRoute(builder: (context) => viewer), ); if (result != null) { Navigator.maybeOf(context)?.maybePop(result); @@ -430,24 +406,9 @@ class FileAssetPickerBuilder selectorProvider: selectorProvider, ), ); - final PageRouteBuilder> pageRoute = PageRouteBuilder>( - pageBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - ) { - return viewer; - }, - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return FadeTransition(opacity: animation, child: child); - }, + return await Navigator.maybeOf(context)?.push?>( + AssetPickerViewerPageRoute(builder: (context) => viewer), ); - return await Navigator.maybeOf(context)?.push?>(pageRoute); } @override diff --git a/lib/src/delegates/asset_picker_builder_delegate.dart b/lib/src/delegates/asset_picker_builder_delegate.dart index 701a7b47..fe569f4b 100644 --- a/lib/src/delegates/asset_picker_builder_delegate.dart +++ b/lib/src/delegates/asset_picker_builder_delegate.dart @@ -25,6 +25,7 @@ import '../models/path_wrapper.dart'; import '../provider/asset_picker_provider.dart'; import '../widget/asset_picker.dart'; import '../widget/asset_picker_app_bar.dart'; +import '../widget/asset_picker_page_route.dart'; import '../widget/asset_picker_viewer.dart'; import '../widget/builder/asset_entity_grid_item_builder.dart'; @@ -48,6 +49,9 @@ abstract class AssetPickerBuilderDelegate { this.pathNameBuilder, this.assetsChangeCallback, this.assetsChangeRefreshPredicate, + this.viewerUseRootNavigator = false, + this.viewerPageRouteSettings, + this.viewerPageRouteBuilder, Color? themeColor, AssetPickerTextDelegate? textDelegate, Locale? locale, @@ -131,6 +135,10 @@ abstract class AssetPickerBuilderDelegate { final AssetsChangeRefreshPredicate? assetsChangeRefreshPredicate; + final bool viewerUseRootNavigator; + final RouteSettings? viewerPageRouteSettings; + final AssetPickerViewerPageRouteBuilder>? viewerPageRouteBuilder; + /// [ThemeData] for the picker. /// 选择器使用的主题 ThemeData get theme => pickerTheme ?? AssetPicker.themeData(themeColor); @@ -834,6 +842,9 @@ class DefaultAssetPickerBuilderDelegate super.pathNameBuilder, super.assetsChangeCallback, super.assetsChangeRefreshPredicate, + super.viewerUseRootNavigator, + super.viewerPageRouteSettings, + super.viewerPageRouteBuilder, super.themeColor, super.textDelegate, super.locale, @@ -1181,6 +1192,9 @@ class DefaultAssetPickerBuilderDelegate maxAssets: p.maxAssets, shouldReversePreview: revert, shouldAutoplayPreview: shouldAutoplayPreview, + useRootNavigator: viewerUseRootNavigator, + pageRouteSettings: viewerPageRouteSettings, + pageRouteBuilder: viewerPageRouteBuilder, ); if (result != null) { Navigator.maybeOf(context)?.maybePop(result); diff --git a/lib/src/delegates/asset_picker_delegate.dart b/lib/src/delegates/asset_picker_delegate.dart index 1d7af894..56e31f78 100644 --- a/lib/src/delegates/asset_picker_delegate.dart +++ b/lib/src/delegates/asset_picker_delegate.dart @@ -68,6 +68,7 @@ class AssetPickerDelegate { AssetPickerConfig pickerConfig = const AssetPickerConfig(), PermissionRequestOption? permissionRequestOption, bool useRootNavigator = true, + RouteSettings? pageRouteSettings, AssetPickerPageRouteBuilder>? pageRouteBuilder, }) async { permissionRequestOption ??= PermissionRequestOption( @@ -83,6 +84,7 @@ class AssetPickerDelegate { pageRouteBuilder?.call(const SizedBox.shrink()) ?? AssetPickerPageRoute>( builder: (_) => const SizedBox.shrink(), + settings: pageRouteSettings, ); final DefaultAssetPickerProvider provider = DefaultAssetPickerProvider( maxAssets: pickerConfig.maxAssets, @@ -127,7 +129,10 @@ class AssetPickerDelegate { rootNavigator: useRootNavigator, )?.push>( pageRouteBuilder?.call(picker) ?? - AssetPickerPageRoute>(builder: (_) => picker), + AssetPickerPageRoute>( + builder: (_) => picker, + settings: pageRouteSettings, + ), ); return result; } @@ -157,6 +162,7 @@ class AssetPickerDelegate { const PermissionRequestOption(), Key? key, bool useRootNavigator = true, + RouteSettings? pageRouteSettings, AssetPickerPageRouteBuilder>? pageRouteBuilder, }) async { await permissionCheck(requestOption: permissionRequestOption); @@ -170,7 +176,10 @@ class AssetPickerDelegate { rootNavigator: useRootNavigator, )?.push>( pageRouteBuilder?.call(picker) ?? - AssetPickerPageRoute>(builder: (_) => picker), + AssetPickerPageRoute>( + builder: (_) => picker, + settings: pageRouteSettings, + ), ); return result; } diff --git a/lib/src/widget/asset_picker.dart b/lib/src/widget/asset_picker.dart index ec22a02d..3db19a60 100644 --- a/lib/src/widget/asset_picker.dart +++ b/lib/src/widget/asset_picker.dart @@ -53,6 +53,7 @@ class AssetPicker extends StatefulWidget { PermissionRequestOption? permissionRequestOption, AssetPickerConfig pickerConfig = const AssetPickerConfig(), bool useRootNavigator = true, + RouteSettings? pageRouteSettings, AssetPickerPageRouteBuilder>? pageRouteBuilder, }) { return _pickerDelegate.pickAssets( @@ -61,6 +62,7 @@ class AssetPicker extends StatefulWidget { pickerConfig: pickerConfig, permissionRequestOption: permissionRequestOption, useRootNavigator: useRootNavigator, + pageRouteSettings: pageRouteSettings, pageRouteBuilder: pageRouteBuilder, ); } @@ -73,6 +75,7 @@ class AssetPicker extends StatefulWidget { PermissionRequestOption permissionRequestOption = const PermissionRequestOption(), Key? key, + RouteSettings? pageRouteSettings, AssetPickerPageRouteBuilder>? pageRouteBuilder, bool useRootNavigator = true, }) { @@ -82,6 +85,7 @@ class AssetPicker extends StatefulWidget { delegate: delegate, permissionRequestOption: permissionRequestOption, useRootNavigator: useRootNavigator, + pageRouteSettings: pageRouteSettings, pageRouteBuilder: pageRouteBuilder, ); } diff --git a/lib/src/widget/asset_picker_page_route.dart b/lib/src/widget/asset_picker_page_route.dart index 7c5ee824..619e9405 100644 --- a/lib/src/widget/asset_picker_page_route.dart +++ b/lib/src/widget/asset_picker_page_route.dart @@ -76,3 +76,67 @@ class AssetPickerPageRoute extends PageRoute { ); } } + +/// Build [AssetPickerViewerPageRoute] with the given generic type. +/// 构建匹配泛型的 [AssetPickerViewerPageRoute] +typedef AssetPickerViewerPageRouteBuilder = AssetPickerViewerPageRoute + Function(Widget viewer); + +/// Built a fade transition for the viewer. +/// 为预览器构造一个渐变的页面过渡动画 +class AssetPickerViewerPageRoute extends PageRoute { + AssetPickerViewerPageRoute({ + required this.builder, + this.transitionCurve = Curves.easeIn, + this.transitionDuration = const Duration(milliseconds: 250), + this.barrierColor, + this.barrierDismissible = false, + this.barrierLabel, + this.maintainState = true, + this.opaque = true, + this.canTransitionFromPredicate, + super.settings, + }); + + final WidgetBuilder builder; + + final Curve transitionCurve; + @override + final Duration transitionDuration; + + @override + final Color? barrierColor; + @override + final bool barrierDismissible; + @override + final String? barrierLabel; + @override + final bool opaque; + @override + final bool maintainState; + + final bool Function(TransitionRoute)? canTransitionFromPredicate; + + @override + bool canTransitionFrom(TransitionRoute previousRoute) => + canTransitionFromPredicate?.call(previousRoute) ?? false; + + @override + Widget buildPage( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + ) { + return builder(context); + } + + @override + Widget buildTransitions( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, + ) { + return FadeTransition(opacity: animation, child: child); + } +} diff --git a/lib/src/widget/asset_picker_viewer.dart b/lib/src/widget/asset_picker_viewer.dart index fe30d20e..b01744f7 100644 --- a/lib/src/widget/asset_picker_viewer.dart +++ b/lib/src/widget/asset_picker_viewer.dart @@ -14,6 +14,7 @@ import '../delegates/asset_picker_viewer_builder_delegate.dart'; import '../provider/asset_picker_provider.dart'; import '../provider/asset_picker_viewer_provider.dart'; import 'asset_picker.dart'; +import 'asset_picker_page_route.dart'; class AssetPickerViewer extends StatefulWidget { const AssetPickerViewer({ @@ -44,6 +45,9 @@ class AssetPickerViewer extends StatefulWidget { PermissionRequestOption permissionRequestOption = const PermissionRequestOption(), bool shouldAutoplayPreview = false, + bool useRootNavigator = false, + RouteSettings? pageRouteSettings, + AssetPickerViewerPageRouteBuilder>? pageRouteBuilder, }) async { if (previewAssets.isEmpty) { throw StateError('Previewing empty assets is not allowed.'); @@ -72,15 +76,13 @@ class AssetPickerViewer extends StatefulWidget { shouldAutoplayPreview: shouldAutoplayPreview, ), ); - final PageRouteBuilder> pageRoute = - PageRouteBuilder>( - pageBuilder: (_, __, ___) => viewer, - transitionsBuilder: (_, Animation animation, __, Widget child) { - return FadeTransition(opacity: animation, child: child); - }, + final List? result = await Navigator.maybeOf( + context, + rootNavigator: useRootNavigator, + )?.push>( + pageRouteBuilder?.call(viewer) ?? + AssetPickerViewerPageRoute(builder: (context) => viewer), ); - final List? result = - await Navigator.maybeOf(context)?.push>(pageRoute); return result; } @@ -91,17 +93,19 @@ class AssetPickerViewer extends StatefulWidget { required AssetPickerViewerBuilderDelegate delegate, PermissionRequestOption permissionRequestOption = const PermissionRequestOption(), + bool useRootNavigator = false, + RouteSettings? pageRouteSettings, + AssetPickerViewerPageRouteBuilder>? pageRouteBuilder, }) async { await AssetPicker.permissionCheck(requestOption: permissionRequestOption); final Widget viewer = AssetPickerViewer(builder: delegate); - final PageRouteBuilder> pageRoute = PageRouteBuilder>( - pageBuilder: (_, __, ___) => viewer, - transitionsBuilder: (_, Animation animation, __, Widget child) { - return FadeTransition(opacity: animation, child: child); - }, + final List? result = await Navigator.maybeOf( + context, + rootNavigator: useRootNavigator, + )?.push>( + pageRouteBuilder?.call(viewer) ?? + AssetPickerViewerPageRoute(builder: (context) => viewer), ); - final List? result = - await Navigator.maybeOf(context)?.push>(pageRoute); return result; } } diff --git a/test/test_utils.dart b/test/test_utils.dart index 9fe5cac0..2f26d17d 100644 --- a/test/test_utils.dart +++ b/test/test_utils.dart @@ -86,6 +86,7 @@ class TestAssetPickerDelegate extends AssetPickerDelegate { AssetPickerConfig pickerConfig = const AssetPickerConfig(), PermissionRequestOption? permissionRequestOption, bool useRootNavigator = true, + RouteSettings? pageRouteSettings, AssetPickerPageRouteBuilder>? pageRouteBuilder, }) async { permissionRequestOption ??= PermissionRequestOption( @@ -149,7 +150,10 @@ class TestAssetPickerDelegate extends AssetPickerDelegate { rootNavigator: useRootNavigator, ).push>( pageRouteBuilder?.call(picker) ?? - AssetPickerPageRoute>(builder: (_) => picker), + AssetPickerPageRoute>( + builder: (_) => picker, + settings: pageRouteSettings, + ), ); return result; }