Skip to content

Commit e1a966b

Browse files
authored
♻️ Expose more route settings (#693)
1 parent e17c1a2 commit e1a966b

File tree

9 files changed

+141
-73
lines changed

9 files changed

+141
-73
lines changed

.github/workflows/runnable.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: Runnable (stable)
22

3+
concurrency:
4+
group: ${{ github.workflow }}-${{ github.ref }}
5+
cancel-in-progress: true
6+
37
on:
48
push:
59
branches:

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ that can be found in the LICENSE file. -->
99
1010
## Unreleased
1111

12+
**New features**
13+
14+
- Expose more route settings. Users are now be able to control the route settings for the picker and viewer.
15+
1216
**Improvements**
1317

1418
- Improve how `MediaQuery` is being listened.

example/lib/customs/pickers/directory_file_asset_picker.dart

Lines changed: 16 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -171,26 +171,10 @@ class _DirectoryFileAssetPickerState extends State<DirectoryFileAssetPicker> {
171171
themeData: AssetPicker.themeData(themeColor),
172172
),
173173
);
174-
final PageRouteBuilder<List<File>> pageRoute =
175-
PageRouteBuilder<List<File>>(
176-
pageBuilder: (
177-
BuildContext context,
178-
Animation<double> animation,
179-
Animation<double> secondaryAnimation,
180-
) {
181-
return viewer;
182-
},
183-
transitionsBuilder: (
184-
BuildContext context,
185-
Animation<double> animation,
186-
Animation<double> secondaryAnimation,
187-
Widget child,
188-
) {
189-
return FadeTransition(opacity: animation, child: child);
190-
},
191-
);
192174
final List<File>? result =
193-
await Navigator.maybeOf(context)?.push<List<File>>(pageRoute);
175+
await Navigator.maybeOf(context)?.push<List<File>>(
176+
AssetPickerViewerPageRoute(builder: (context) => viewer),
177+
);
194178
if (result != null && result != fileList) {
195179
fileList
196180
..clear()
@@ -384,27 +368,19 @@ class FileAssetPickerBuilder
384368
int? index,
385369
File currentAsset,
386370
) async {
371+
final Widget viewer = AssetPickerViewer<File, Directory>(
372+
builder: FileAssetPickerViewerBuilderDelegate(
373+
currentIndex: index ?? provider.selectedAssets.indexOf(currentAsset),
374+
previewAssets: provider.selectedAssets,
375+
provider: FileAssetPickerViewerProvider(provider.selectedAssets),
376+
themeData: AssetPicker.themeData(themeColor),
377+
selectedAssets: provider.selectedAssets,
378+
selectorProvider: provider,
379+
),
380+
);
387381
final List<File>? result =
388382
await Navigator.maybeOf(context)?.push<List<File>?>(
389-
PageRouteBuilder<List<File>>(
390-
pageBuilder: (
391-
BuildContext context,
392-
Animation<double> animation,
393-
Animation<double> secondaryAnimation,
394-
) {
395-
return AssetPickerViewer<File, Directory>(
396-
builder: FileAssetPickerViewerBuilderDelegate(
397-
currentIndex:
398-
index ?? provider.selectedAssets.indexOf(currentAsset),
399-
previewAssets: provider.selectedAssets,
400-
provider: FileAssetPickerViewerProvider(provider.selectedAssets),
401-
themeData: AssetPicker.themeData(themeColor),
402-
selectedAssets: provider.selectedAssets,
403-
selectorProvider: provider,
404-
),
405-
);
406-
},
407-
),
383+
AssetPickerViewerPageRoute(builder: (context) => viewer),
408384
);
409385
if (result != null) {
410386
Navigator.maybeOf(context)?.maybePop(result);
@@ -430,24 +406,9 @@ class FileAssetPickerBuilder
430406
selectorProvider: selectorProvider,
431407
),
432408
);
433-
final PageRouteBuilder<List<File>> pageRoute = PageRouteBuilder<List<File>>(
434-
pageBuilder: (
435-
BuildContext context,
436-
Animation<double> animation,
437-
Animation<double> secondaryAnimation,
438-
) {
439-
return viewer;
440-
},
441-
transitionsBuilder: (
442-
BuildContext context,
443-
Animation<double> animation,
444-
Animation<double> secondaryAnimation,
445-
Widget child,
446-
) {
447-
return FadeTransition(opacity: animation, child: child);
448-
},
409+
return await Navigator.maybeOf(context)?.push<List<File>?>(
410+
AssetPickerViewerPageRoute(builder: (context) => viewer),
449411
);
450-
return await Navigator.maybeOf(context)?.push<List<File>?>(pageRoute);
451412
}
452413

453414
@override

lib/src/delegates/asset_picker_builder_delegate.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import '../models/path_wrapper.dart';
2525
import '../provider/asset_picker_provider.dart';
2626
import '../widget/asset_picker.dart';
2727
import '../widget/asset_picker_app_bar.dart';
28+
import '../widget/asset_picker_page_route.dart';
2829
import '../widget/asset_picker_viewer.dart';
2930
import '../widget/builder/asset_entity_grid_item_builder.dart';
3031

@@ -48,6 +49,9 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
4849
this.pathNameBuilder,
4950
this.assetsChangeCallback,
5051
this.assetsChangeRefreshPredicate,
52+
this.viewerUseRootNavigator = false,
53+
this.viewerPageRouteSettings,
54+
this.viewerPageRouteBuilder,
5155
Color? themeColor,
5256
AssetPickerTextDelegate? textDelegate,
5357
Locale? locale,
@@ -131,6 +135,10 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
131135
final AssetsChangeRefreshPredicate<AssetPathEntity>?
132136
assetsChangeRefreshPredicate;
133137

138+
final bool viewerUseRootNavigator;
139+
final RouteSettings? viewerPageRouteSettings;
140+
final AssetPickerViewerPageRouteBuilder<List<Asset>>? viewerPageRouteBuilder;
141+
134142
/// [ThemeData] for the picker.
135143
/// 选择器使用的主题
136144
ThemeData get theme => pickerTheme ?? AssetPicker.themeData(themeColor);
@@ -828,6 +836,9 @@ class DefaultAssetPickerBuilderDelegate
828836
super.pathNameBuilder,
829837
super.assetsChangeCallback,
830838
super.assetsChangeRefreshPredicate,
839+
super.viewerUseRootNavigator,
840+
super.viewerPageRouteSettings,
841+
super.viewerPageRouteBuilder,
831842
super.themeColor,
832843
super.textDelegate,
833844
super.locale,
@@ -1175,6 +1186,9 @@ class DefaultAssetPickerBuilderDelegate
11751186
maxAssets: p.maxAssets,
11761187
shouldReversePreview: revert,
11771188
shouldAutoplayPreview: shouldAutoplayPreview,
1189+
useRootNavigator: viewerUseRootNavigator,
1190+
pageRouteSettings: viewerPageRouteSettings,
1191+
pageRouteBuilder: viewerPageRouteBuilder,
11781192
);
11791193
if (result != null) {
11801194
Navigator.maybeOf(context)?.maybePop(result);

lib/src/delegates/asset_picker_delegate.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class AssetPickerDelegate {
6868
AssetPickerConfig pickerConfig = const AssetPickerConfig(),
6969
PermissionRequestOption? permissionRequestOption,
7070
bool useRootNavigator = true,
71+
RouteSettings? pageRouteSettings,
7172
AssetPickerPageRouteBuilder<List<AssetEntity>>? pageRouteBuilder,
7273
}) async {
7374
permissionRequestOption ??= PermissionRequestOption(
@@ -83,6 +84,7 @@ class AssetPickerDelegate {
8384
pageRouteBuilder?.call(const SizedBox.shrink()) ??
8485
AssetPickerPageRoute<List<AssetEntity>>(
8586
builder: (_) => const SizedBox.shrink(),
87+
settings: pageRouteSettings,
8688
);
8789
final DefaultAssetPickerProvider provider = DefaultAssetPickerProvider(
8890
maxAssets: pickerConfig.maxAssets,
@@ -127,7 +129,10 @@ class AssetPickerDelegate {
127129
rootNavigator: useRootNavigator,
128130
)?.push<List<AssetEntity>>(
129131
pageRouteBuilder?.call(picker) ??
130-
AssetPickerPageRoute<List<AssetEntity>>(builder: (_) => picker),
132+
AssetPickerPageRoute<List<AssetEntity>>(
133+
builder: (_) => picker,
134+
settings: pageRouteSettings,
135+
),
131136
);
132137
return result;
133138
}
@@ -157,6 +162,7 @@ class AssetPickerDelegate {
157162
const PermissionRequestOption(),
158163
Key? key,
159164
bool useRootNavigator = true,
165+
RouteSettings? pageRouteSettings,
160166
AssetPickerPageRouteBuilder<List<Asset>>? pageRouteBuilder,
161167
}) async {
162168
await permissionCheck(requestOption: permissionRequestOption);
@@ -170,7 +176,10 @@ class AssetPickerDelegate {
170176
rootNavigator: useRootNavigator,
171177
)?.push<List<Asset>>(
172178
pageRouteBuilder?.call(picker) ??
173-
AssetPickerPageRoute<List<Asset>>(builder: (_) => picker),
179+
AssetPickerPageRoute<List<Asset>>(
180+
builder: (_) => picker,
181+
settings: pageRouteSettings,
182+
),
174183
);
175184
return result;
176185
}

lib/src/widget/asset_picker.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class AssetPicker<Asset, Path> extends StatefulWidget {
5353
PermissionRequestOption? permissionRequestOption,
5454
AssetPickerConfig pickerConfig = const AssetPickerConfig(),
5555
bool useRootNavigator = true,
56+
RouteSettings? pageRouteSettings,
5657
AssetPickerPageRouteBuilder<List<AssetEntity>>? pageRouteBuilder,
5758
}) {
5859
return _pickerDelegate.pickAssets(
@@ -61,6 +62,7 @@ class AssetPicker<Asset, Path> extends StatefulWidget {
6162
pickerConfig: pickerConfig,
6263
permissionRequestOption: permissionRequestOption,
6364
useRootNavigator: useRootNavigator,
65+
pageRouteSettings: pageRouteSettings,
6466
pageRouteBuilder: pageRouteBuilder,
6567
);
6668
}
@@ -73,6 +75,7 @@ class AssetPicker<Asset, Path> extends StatefulWidget {
7375
PermissionRequestOption permissionRequestOption =
7476
const PermissionRequestOption(),
7577
Key? key,
78+
RouteSettings? pageRouteSettings,
7679
AssetPickerPageRouteBuilder<List<Asset>>? pageRouteBuilder,
7780
bool useRootNavigator = true,
7881
}) {
@@ -82,6 +85,7 @@ class AssetPicker<Asset, Path> extends StatefulWidget {
8285
delegate: delegate,
8386
permissionRequestOption: permissionRequestOption,
8487
useRootNavigator: useRootNavigator,
88+
pageRouteSettings: pageRouteSettings,
8589
pageRouteBuilder: pageRouteBuilder,
8690
);
8791
}

lib/src/widget/asset_picker_page_route.dart

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,67 @@ class AssetPickerPageRoute<T> extends PageRoute<T> {
7676
);
7777
}
7878
}
79+
80+
/// Build [AssetPickerViewerPageRoute] with the given generic type.
81+
/// 构建匹配泛型的 [AssetPickerViewerPageRoute]
82+
typedef AssetPickerViewerPageRouteBuilder<T> = AssetPickerViewerPageRoute<T>
83+
Function(Widget viewer);
84+
85+
/// Built a fade transition for the viewer.
86+
/// 为预览器构造一个渐变的页面过渡动画
87+
class AssetPickerViewerPageRoute<T> extends PageRoute<T> {
88+
AssetPickerViewerPageRoute({
89+
required this.builder,
90+
this.transitionCurve = Curves.easeIn,
91+
this.transitionDuration = const Duration(milliseconds: 250),
92+
this.barrierColor,
93+
this.barrierDismissible = false,
94+
this.barrierLabel,
95+
this.maintainState = true,
96+
this.opaque = true,
97+
this.canTransitionFromPredicate,
98+
super.settings,
99+
});
100+
101+
final WidgetBuilder builder;
102+
103+
final Curve transitionCurve;
104+
@override
105+
final Duration transitionDuration;
106+
107+
@override
108+
final Color? barrierColor;
109+
@override
110+
final bool barrierDismissible;
111+
@override
112+
final String? barrierLabel;
113+
@override
114+
final bool opaque;
115+
@override
116+
final bool maintainState;
117+
118+
final bool Function(TransitionRoute<dynamic>)? canTransitionFromPredicate;
119+
120+
@override
121+
bool canTransitionFrom(TransitionRoute<dynamic> previousRoute) =>
122+
canTransitionFromPredicate?.call(previousRoute) ?? false;
123+
124+
@override
125+
Widget buildPage(
126+
BuildContext context,
127+
Animation<double> animation,
128+
Animation<double> secondaryAnimation,
129+
) {
130+
return builder(context);
131+
}
132+
133+
@override
134+
Widget buildTransitions(
135+
BuildContext context,
136+
Animation<double> animation,
137+
Animation<double> secondaryAnimation,
138+
Widget child,
139+
) {
140+
return FadeTransition(opacity: animation, child: child);
141+
}
142+
}

lib/src/widget/asset_picker_viewer.dart

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import '../delegates/asset_picker_viewer_builder_delegate.dart';
1414
import '../provider/asset_picker_provider.dart';
1515
import '../provider/asset_picker_viewer_provider.dart';
1616
import 'asset_picker.dart';
17+
import 'asset_picker_page_route.dart';
1718

1819
class AssetPickerViewer<Asset, Path> extends StatefulWidget {
1920
const AssetPickerViewer({
@@ -44,6 +45,9 @@ class AssetPickerViewer<Asset, Path> extends StatefulWidget {
4445
PermissionRequestOption permissionRequestOption =
4546
const PermissionRequestOption(),
4647
bool shouldAutoplayPreview = false,
48+
bool useRootNavigator = false,
49+
RouteSettings? pageRouteSettings,
50+
AssetPickerViewerPageRouteBuilder<List<AssetEntity>>? pageRouteBuilder,
4751
}) async {
4852
if (previewAssets.isEmpty) {
4953
throw StateError('Previewing empty assets is not allowed.');
@@ -72,15 +76,13 @@ class AssetPickerViewer<Asset, Path> extends StatefulWidget {
7276
shouldAutoplayPreview: shouldAutoplayPreview,
7377
),
7478
);
75-
final PageRouteBuilder<List<AssetEntity>> pageRoute =
76-
PageRouteBuilder<List<AssetEntity>>(
77-
pageBuilder: (_, __, ___) => viewer,
78-
transitionsBuilder: (_, Animation<double> animation, __, Widget child) {
79-
return FadeTransition(opacity: animation, child: child);
80-
},
79+
final List<AssetEntity>? result = await Navigator.maybeOf(
80+
context,
81+
rootNavigator: useRootNavigator,
82+
)?.push<List<AssetEntity>>(
83+
pageRouteBuilder?.call(viewer) ??
84+
AssetPickerViewerPageRoute(builder: (context) => viewer),
8185
);
82-
final List<AssetEntity>? result =
83-
await Navigator.maybeOf(context)?.push<List<AssetEntity>>(pageRoute);
8486
return result;
8587
}
8688

@@ -91,17 +93,19 @@ class AssetPickerViewer<Asset, Path> extends StatefulWidget {
9193
required AssetPickerViewerBuilderDelegate<A, P> delegate,
9294
PermissionRequestOption permissionRequestOption =
9395
const PermissionRequestOption(),
96+
bool useRootNavigator = false,
97+
RouteSettings? pageRouteSettings,
98+
AssetPickerViewerPageRouteBuilder<List<A>>? pageRouteBuilder,
9499
}) async {
95100
await AssetPicker.permissionCheck(requestOption: permissionRequestOption);
96101
final Widget viewer = AssetPickerViewer<A, P>(builder: delegate);
97-
final PageRouteBuilder<List<A>> pageRoute = PageRouteBuilder<List<A>>(
98-
pageBuilder: (_, __, ___) => viewer,
99-
transitionsBuilder: (_, Animation<double> animation, __, Widget child) {
100-
return FadeTransition(opacity: animation, child: child);
101-
},
102+
final List<A>? result = await Navigator.maybeOf(
103+
context,
104+
rootNavigator: useRootNavigator,
105+
)?.push<List<A>>(
106+
pageRouteBuilder?.call(viewer) ??
107+
AssetPickerViewerPageRoute(builder: (context) => viewer),
102108
);
103-
final List<A>? result =
104-
await Navigator.maybeOf(context)?.push<List<A>>(pageRoute);
105109
return result;
106110
}
107111
}

0 commit comments

Comments
 (0)