@@ -269,68 +269,42 @@ abstract class AssetPickerBuilderDelegate<A, P> {
269
269
);
270
270
}
271
271
272
+ /// The effective direction for the assets grid.
273
+ /// 网格实际的方向
274
+ ///
275
+ /// By default, the direction will be reversed if it's iOS/macOS.
276
+ /// 默认情况下,在 iOS/macOS 上方向会反向。
277
+ TextDirection effectiveGridDirection (BuildContext context) {
278
+ final TextDirection _od = Directionality .of (context);
279
+ if (isAppleOS) {
280
+ if (_od == TextDirection .ltr) {
281
+ return TextDirection .rtl;
282
+ }
283
+ return TextDirection .ltr;
284
+ }
285
+ return _od;
286
+ }
287
+
272
288
/// The main grid view builder for assets.
273
289
/// 主要的资源查看网格部件
274
- Widget assetsGridBuilder (BuildContext context) {
275
- return ColoredBox (
276
- color: theme.canvasColor,
277
- child: Selector <AssetPickerProvider <A , P >, List <A >>(
278
- selector: (_, AssetPickerProvider <A , P > provider) =>
279
- provider.currentAssets,
280
- builder: (_, List <A > currentAssets, __) => CustomScrollView (
281
- controller: gridScrollController,
282
- slivers: < Widget > [
283
- if (isAppleOS)
284
- SliverToBoxAdapter (
285
- child: SizedBox (
286
- height: Screens .topSafeHeight + kToolbarHeight,
287
- ),
288
- ),
289
- SliverGrid (
290
- delegate: SliverChildBuilderDelegate (
291
- (_, int index) => Builder (
292
- builder: (BuildContext c) => assetGridItemBuilder (
293
- c,
294
- index,
295
- currentAssets,
296
- ),
297
- ),
298
- childCount: assetsGridItemCount (_, currentAssets),
299
- findChildIndexCallback: (Key ? key) {
300
- if (key is ValueKey <String >) {
301
- return findChildIndexBuilder (
302
- key.value,
303
- currentAssets,
304
- );
305
- }
306
- return null ;
307
- },
308
- ),
309
- gridDelegate: SliverGridDelegateWithFixedCrossAxisCount (
310
- crossAxisCount: gridCount,
311
- mainAxisSpacing: itemSpacing,
312
- crossAxisSpacing: itemSpacing,
313
- ),
314
- ),
315
- if (isAppleOS)
316
- SliverToBoxAdapter (
317
- child: SizedBox (
318
- height: Screens .bottomSafeHeight + bottomActionBarHeight,
319
- ),
320
- ),
321
- ],
322
- ),
323
- ),
324
- );
325
- }
290
+ Widget assetsGridBuilder (BuildContext context);
326
291
327
292
/// Indicates how would the grid found a reusable [RenderObject] through [id] .
328
293
/// 为 Grid 布局指示如何找到可复用的 [RenderObject] 。
329
- int ? findChildIndexBuilder (String id, List <A > currentAssets) => null ;
294
+ int ? findChildIndexBuilder ({
295
+ required String id,
296
+ required List <A > assets,
297
+ int placeholderCount = 0 ,
298
+ }) =>
299
+ null ;
330
300
331
301
/// The function which return items count for the assets' grid.
332
302
/// 为资源列表提供内容数量计算的方法
333
- int assetsGridItemCount (BuildContext context, List <A > currentAssets);
303
+ int assetsGridItemCount ({
304
+ required BuildContext context,
305
+ required List <A > assets,
306
+ int placeholderCount = 0 ,
307
+ });
334
308
335
309
/// The item builder for the assets' grid.
336
310
/// 资源列表项的构建
@@ -680,6 +654,8 @@ class DefaultAssetPickerBuilderDelegate
680
654
/// 资源的预览是否启用
681
655
bool get isPreviewEnabled => specialPickerType != SpecialPickerType .noPreview;
682
656
657
+ final GlobalKey _gridRevertKey = GlobalKey ();
658
+
683
659
@override
684
660
Widget androidLayout (BuildContext context) {
685
661
return FixedAppBarWrapper (
@@ -779,6 +755,118 @@ class DefaultAssetPickerBuilderDelegate
779
755
);
780
756
}
781
757
758
+ @override
759
+ Widget assetsGridBuilder (BuildContext context) {
760
+ // First, we need the count of the assets.
761
+ final int totalCount = provider.currentPathEntity! .assetCount;
762
+ // Then we use the total count to calculate how many placeholders we need.
763
+ final int _placeholderCount;
764
+ if (isAppleOS) {
765
+ _placeholderCount =
766
+ totalCount % gridCount == 0 ? 0 : gridCount - totalCount % gridCount;
767
+ } else {
768
+ _placeholderCount = 0 ;
769
+ }
770
+
771
+ Widget _sliverGrid (BuildContext c, List <AssetEntity > assets) {
772
+ return SliverGrid (
773
+ delegate: SliverChildBuilderDelegate (
774
+ (_, int index) => Builder (
775
+ builder: (BuildContext c) {
776
+ if (isAppleOS) {
777
+ if (index < _placeholderCount) {
778
+ return const SizedBox .shrink ();
779
+ }
780
+ index -= _placeholderCount;
781
+ }
782
+ return Directionality (
783
+ textDirection: Directionality .of (context),
784
+ child: assetGridItemBuilder (c, index, assets),
785
+ );
786
+ },
787
+ ),
788
+ childCount: assetsGridItemCount (
789
+ context: c,
790
+ assets: assets,
791
+ placeholderCount: _placeholderCount,
792
+ ),
793
+ findChildIndexCallback: (Key ? key) {
794
+ if (key is ValueKey <String >) {
795
+ return findChildIndexBuilder (
796
+ id: key.value,
797
+ assets: assets,
798
+ placeholderCount: _placeholderCount,
799
+ );
800
+ }
801
+ return null ;
802
+ },
803
+ ),
804
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount (
805
+ crossAxisCount: gridCount,
806
+ mainAxisSpacing: itemSpacing,
807
+ crossAxisSpacing: itemSpacing,
808
+ ),
809
+ );
810
+ }
811
+
812
+ return LayoutBuilder (
813
+ builder: (BuildContext c, BoxConstraints constraints) {
814
+ final double topPadding = c.mediaQuery.padding.top + kToolbarHeight;
815
+ final double bottomPadding =
816
+ c.mediaQuery.padding.bottom + bottomActionBarHeight;
817
+ final double verticalPadding = topPadding + bottomPadding;
818
+
819
+ final int _count = totalCount + _placeholderCount;
820
+ final double _wWidth = constraints.maxWidth;
821
+ final double _wHeight = constraints.maxHeight - topPadding;
822
+ final double _itemSize = _wWidth / gridCount;
823
+ final double anchor;
824
+ if (_count <= gridCount) {
825
+ anchor = verticalPadding / _wHeight;
826
+ } else {
827
+ anchor = math.min (
828
+ _count ~ / gridCount * _itemSize / _wHeight,
829
+ 1 ,
830
+ );
831
+ }
832
+
833
+ return Directionality (
834
+ textDirection: effectiveGridDirection (context),
835
+ child: ColoredBox (
836
+ color: theme.canvasColor,
837
+ child: Selector <DefaultAssetPickerProvider , List <AssetEntity >>(
838
+ selector: (_, DefaultAssetPickerProvider provider) =>
839
+ provider.currentAssets,
840
+ builder: (BuildContext c, List <AssetEntity > assets, __) {
841
+ return CustomScrollView (
842
+ physics: const AlwaysScrollableScrollPhysics (),
843
+ controller: gridScrollController,
844
+ anchor: isAppleOS ? anchor : 0 ,
845
+ center: isAppleOS ? _gridRevertKey : null ,
846
+ slivers: < Widget > [
847
+ if (isAppleOS)
848
+ SliverToBoxAdapter (
849
+ child: SizedBox (
850
+ height:
851
+ context.mediaQuery.padding.top + kToolbarHeight,
852
+ ),
853
+ ),
854
+ _sliverGrid (c, assets),
855
+ if (isAppleOS)
856
+ SliverToBoxAdapter (
857
+ key: _gridRevertKey,
858
+ child: const SizedBox .shrink (),
859
+ ),
860
+ ],
861
+ );
862
+ },
863
+ ),
864
+ ),
865
+ );
866
+ },
867
+ );
868
+ }
869
+
782
870
/// There are several conditions within this builder:
783
871
/// * Return [specialItemBuilder] while the current path is all and
784
872
/// [specialItemPosition] is not equal to [SpecialItemPosition.none].
@@ -873,19 +961,25 @@ class DefaultAssetPickerBuilderDelegate
873
961
}
874
962
875
963
@override
876
- int findChildIndexBuilder (String id, List <AssetEntity > currentAssets) {
877
- int index = currentAssets.indexWhere ((AssetEntity e) => e.id == id);
964
+ int findChildIndexBuilder ({
965
+ required String id,
966
+ required List <AssetEntity > assets,
967
+ int placeholderCount = 0 ,
968
+ }) {
969
+ int index = assets.indexWhere ((AssetEntity e) => e.id == id);
878
970
if (specialItemPosition == SpecialItemPosition .prepend) {
879
971
index += 1 ;
880
972
}
973
+ index += placeholderCount;
881
974
return index;
882
975
}
883
976
884
977
@override
885
- int assetsGridItemCount (
886
- BuildContext context,
887
- List <AssetEntity > currentAssets,
888
- ) {
978
+ int assetsGridItemCount ({
979
+ required BuildContext context,
980
+ required List <AssetEntity > assets,
981
+ int placeholderCount = 0 ,
982
+ }) {
889
983
final AssetPathEntity ? currentPathEntity =
890
984
context.select <DefaultAssetPickerProvider , AssetPathEntity ?>(
891
985
(DefaultAssetPickerProvider p) => p.currentPathEntity,
@@ -898,7 +992,7 @@ class DefaultAssetPickerBuilderDelegate
898
992
899
993
/// Return actual length if current path is all.
900
994
/// 如果当前目录是全部内容,则返回实际的内容数量。
901
- final int _length = currentAssets .length;
995
+ final int _length = assets .length + placeholderCount ;
902
996
if (! currentPathEntity! .isAll) {
903
997
return _length;
904
998
}
0 commit comments