@@ -369,23 +369,25 @@ class FileAssetPickerProvider extends AssetPickerProvider<File, Directory> {
369
369
}
370
370
371
371
@override
372
- void switchPath (Directory pathEntity) {
372
+ Future <void > switchPath ([Directory ? pathEntity]) async {
373
+ if (pathEntity == null ) {
374
+ return ;
375
+ }
373
376
isSwitchingPath = false ;
374
377
currentPathEntity = pathEntity;
375
378
totalAssetsCount = 0 ;
376
379
notifyListeners ();
377
- getAssetsFromEntity (0 , currentPathEntity! );
380
+ await getAssetsFromEntity (0 , currentPathEntity! );
378
381
}
379
382
}
380
383
381
384
class FileAssetPickerBuilder
382
385
extends AssetPickerBuilderDelegate <File , Directory > {
383
386
FileAssetPickerBuilder ({
384
387
required FileAssetPickerProvider provider,
385
- }) : super (provider: provider);
388
+ }) : super (provider: provider, initialPermission : PermissionState .authorized );
386
389
387
- AssetsPickerTextDelegate get textDelegate =>
388
- DefaultAssetsPickerTextDelegate ();
390
+ AssetsPickerTextDelegate get textDelegate => AssetsPickerTextDelegate ();
389
391
390
392
Duration get switchingPathDuration => kThemeAnimationDuration * 1.5 ;
391
393
@@ -533,6 +535,120 @@ class FileAssetPickerBuilder
533
535
);
534
536
}
535
537
538
+ @override
539
+ Widget assetsGridBuilder (BuildContext context) {
540
+ int totalCount = provider.currentAssets.length;
541
+ if (specialItemPosition != SpecialItemPosition .none) {
542
+ totalCount += 1 ;
543
+ }
544
+ final int placeholderCount;
545
+ if (isAppleOS && totalCount % gridCount != 0 ) {
546
+ placeholderCount = gridCount - totalCount % gridCount;
547
+ } else {
548
+ placeholderCount = 0 ;
549
+ }
550
+ final int row = (totalCount + placeholderCount) ~ / gridCount;
551
+ final double dividedSpacing = itemSpacing / gridCount;
552
+ final double topPadding =
553
+ MediaQuery .of (context).padding.top + kToolbarHeight;
554
+
555
+ Widget _sliverGrid (BuildContext ctx, List <File > assets) {
556
+ return SliverGrid (
557
+ delegate: SliverChildBuilderDelegate (
558
+ (_, int index) => Builder (
559
+ builder: (BuildContext c) {
560
+ if (isAppleOS) {
561
+ if (index < placeholderCount) {
562
+ return const SizedBox .shrink ();
563
+ }
564
+ index -= placeholderCount;
565
+ }
566
+ return Directionality (
567
+ textDirection: Directionality .of (context),
568
+ child: assetGridItemBuilder (c, index, assets),
569
+ );
570
+ },
571
+ ),
572
+ childCount: assetsGridItemCount (
573
+ context: ctx,
574
+ assets: assets,
575
+ placeholderCount: placeholderCount,
576
+ ),
577
+ findChildIndexCallback: (Key ? key) {
578
+ if (key is ValueKey <String >) {
579
+ return findChildIndexBuilder (
580
+ id: key.value,
581
+ assets: assets,
582
+ placeholderCount: placeholderCount,
583
+ );
584
+ }
585
+ return null ;
586
+ },
587
+ ),
588
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount (
589
+ crossAxisCount: gridCount,
590
+ mainAxisSpacing: itemSpacing,
591
+ crossAxisSpacing: itemSpacing,
592
+ ),
593
+ );
594
+ }
595
+
596
+ return LayoutBuilder (
597
+ builder: (BuildContext c, BoxConstraints constraints) {
598
+ final double _itemSize = constraints.maxWidth / gridCount;
599
+ // Use [ScrollView.anchor] to determine where is the first place of
600
+ // the [SliverGrid]. Each row needs [dividedSpacing] to calculate,
601
+ // then minus one times of [itemSpacing] because spacing's count in the
602
+ // cross axis is always less than the rows.
603
+ final double anchor = math.min (
604
+ (row * (_itemSize + dividedSpacing) + topPadding - itemSpacing) /
605
+ constraints.maxHeight,
606
+ 1 ,
607
+ );
608
+
609
+ return Directionality (
610
+ textDirection: effectiveGridDirection (context),
611
+ child: ColoredBox (
612
+ color: theme.canvasColor,
613
+ child: Selector <FileAssetPickerProvider , List <File >>(
614
+ selector: (_, FileAssetPickerProvider provider) =>
615
+ provider.currentAssets,
616
+ builder: (_, List <File > assets, __) => CustomScrollView (
617
+ physics: const AlwaysScrollableScrollPhysics (),
618
+ controller: gridScrollController,
619
+ anchor: isAppleOS ? anchor : 0 ,
620
+ center: isAppleOS ? gridRevertKey : null ,
621
+ slivers: < Widget > [
622
+ if (isAppleOS)
623
+ SliverToBoxAdapter (
624
+ child: SizedBox (
625
+ height:
626
+ MediaQuery .of (context).padding.top + kToolbarHeight,
627
+ ),
628
+ ),
629
+ _sliverGrid (_, assets),
630
+ // Ignore the gap when the [anchor] is not equal to 1.
631
+ if (isAppleOS && anchor == 1 )
632
+ SliverToBoxAdapter (
633
+ child: SizedBox (
634
+ height: MediaQuery .of (context).padding.bottom +
635
+ bottomSectionHeight,
636
+ ),
637
+ ),
638
+ if (isAppleOS)
639
+ SliverToBoxAdapter (
640
+ key: gridRevertKey,
641
+ child: const SizedBox .shrink (),
642
+ ),
643
+ ],
644
+ ),
645
+ ),
646
+ ),
647
+ );
648
+ },
649
+ );
650
+ }
651
+
536
652
@override
537
653
Widget assetGridItemBuilder (
538
654
BuildContext context,
@@ -567,18 +683,22 @@ class FileAssetPickerBuilder
567
683
}
568
684
569
685
@override
570
- int assetsGridItemCount (BuildContext context, List <File > currentAssets) {
686
+ int assetsGridItemCount ({
687
+ required BuildContext context,
688
+ required List <File > assets,
689
+ int placeholderCount = 0 ,
690
+ }) {
571
691
int length;
572
692
switch (specialItemPosition) {
573
693
case SpecialItemPosition .none:
574
- length = currentAssets .length;
694
+ length = assets .length;
575
695
break ;
576
696
case SpecialItemPosition .prepend:
577
697
case SpecialItemPosition .append:
578
- length = currentAssets .length + 1 ;
698
+ length = assets .length + 1 ;
579
699
break ;
580
700
}
581
- return length;
701
+ return length + placeholderCount ;
582
702
}
583
703
584
704
@override
@@ -1047,8 +1167,12 @@ class FileAssetPickerBuilder
1047
1167
}
1048
1168
1049
1169
@override
1050
- int findChildIndexBuilder (String id, List <File > currentAssets) {
1051
- return currentAssets.indexWhere ((File file) => file.path == id);
1170
+ int findChildIndexBuilder ({
1171
+ required String id,
1172
+ required List <File > assets,
1173
+ int placeholderCount = 0 ,
1174
+ }) {
1175
+ return assets.indexWhere ((File file) => file.path == id);
1052
1176
}
1053
1177
}
1054
1178
@@ -1091,8 +1215,7 @@ class FileAssetPickerViewerBuilderDelegate
1091
1215
1092
1216
late final PageController pageController;
1093
1217
1094
- AssetsPickerTextDelegate get textDelegate =>
1095
- DefaultAssetsPickerTextDelegate ();
1218
+ AssetsPickerTextDelegate get textDelegate => AssetsPickerTextDelegate ();
1096
1219
1097
1220
void switchDisplayingDetail ({bool ? value}) {
1098
1221
isDisplayingDetail = value ?? ! isDisplayingDetail;
0 commit comments