Skip to content

Commit caaa1a2

Browse files
committed
Fix wrong special item calculation and naming.
1 parent dabb68c commit caaa1a2

File tree

2 files changed

+126
-61
lines changed

2 files changed

+126
-61
lines changed

example/lib/customs/pickers/directory_file_asset_picker.dart

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -584,9 +584,28 @@ class FileAssetPickerBuilder
584584
Widget assetsGridBuilder(BuildContext context) {
585585
appBarPreferredSize ??= appBar(context).preferredSize;
586586
int totalCount = provider.currentAssets.length;
587-
if (specialItems.isNotEmpty) {
588-
totalCount += specialItems.length;
589-
}
587+
588+
final List<SpecialItemResult> specialItemResults = specialItems
589+
.map((item) {
590+
final specialItem = item.builder?.call(
591+
context,
592+
provider.currentPath?.path,
593+
totalCount,
594+
permissionNotifier.value,
595+
);
596+
if (specialItem != null) {
597+
return SpecialItemResult(
598+
position: item.position,
599+
item: specialItem,
600+
);
601+
}
602+
return null;
603+
})
604+
.whereType<SpecialItemResult>()
605+
.toList();
606+
607+
totalCount += specialItemResults.length;
608+
590609
final int placeholderCount;
591610
if (isAppleOS(context) && totalCount % gridCount != 0) {
592611
placeholderCount = gridCount - totalCount % gridCount;
@@ -626,6 +645,11 @@ class FileAssetPickerBuilder
626645
id: key.value,
627646
assets: assets,
628647
placeholderCount: placeholderCount,
648+
prependSpecialItemResults: specialItemResults
649+
.where(
650+
(item) => item.position == SpecialItemPosition.prepend,
651+
)
652+
.toList(),
629653
);
630654
}
631655
return null;
@@ -699,9 +723,36 @@ class FileAssetPickerBuilder
699723
Widget assetGridItemBuilder(
700724
BuildContext context,
701725
int index,
702-
List<File> currentAssets,
703-
) {
704-
final currentIndex = index - prependSpecialItems.length;
726+
List<File> currentAssets, {
727+
List<SpecialItemResult> specialItemResults = const [],
728+
}) {
729+
final int length = currentAssets.length;
730+
731+
final prependItems = <SpecialItemResult>[];
732+
final appendItems = <SpecialItemResult>[];
733+
for (final model in specialItemResults) {
734+
switch (model.position) {
735+
case SpecialItemPosition.prepend:
736+
prependItems.add(model);
737+
case SpecialItemPosition.append:
738+
appendItems.add(model);
739+
}
740+
}
741+
742+
if (prependItems.isNotEmpty) {
743+
if (index < prependItems.length) {
744+
return specialItemResults[index].item;
745+
}
746+
}
747+
748+
if (appendItems.isNotEmpty) {
749+
if (index >= length + prependItems.length) {
750+
return specialItemResults[index - length].item;
751+
}
752+
}
753+
754+
final currentIndex = index - prependItems.length;
755+
705756
final File asset = currentAssets.elementAt(currentIndex);
706757
final Widget builder = imageAndVideoItemBuilder(
707758
context,
@@ -724,6 +775,7 @@ class FileAssetPickerBuilder
724775
int index,
725776
File asset,
726777
Widget child,
778+
List<SpecialItemResult> prependSpecialItemResults,
727779
) {
728780
return Semantics(child: child);
729781
}
@@ -1161,6 +1213,7 @@ class FileAssetPickerBuilder
11611213
int findChildIndexBuilder({
11621214
required String id,
11631215
required List<File> assets,
1216+
required List<SpecialItemResult> prependSpecialItemResults,
11641217
int placeholderCount = 0,
11651218
}) {
11661219
return assets.indexWhere((File file) => file.path == id);

lib/src/delegates/asset_picker_builder_delegate.dart

Lines changed: 67 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,17 @@ import '../widget/asset_picker_app_bar.dart';
2828
import '../widget/asset_picker_viewer.dart';
2929
import '../widget/builder/asset_entity_grid_item_builder.dart';
3030

31-
typedef _SpecialItemModel = ({
32-
SpecialItemPosition position,
33-
Widget item,
34-
});
31+
/// Class which contains non-null special item widget and its position which derived from the [SpecialItem]
32+
/// 包含非空自定义item,并指定其位置。
33+
class SpecialItemResult {
34+
SpecialItemResult({
35+
required this.position,
36+
required this.item,
37+
});
38+
39+
SpecialItemPosition position;
40+
Widget item;
41+
}
3542

3643
/// The delegate to build the whole picker's components.
3744
///
@@ -62,17 +69,7 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
6269
),
6370
themeColor = pickerTheme?.colorScheme.secondary ??
6471
themeColor ??
65-
defaultThemeColorWeChat,
66-
prependSpecialItems = specialItems
67-
.where(
68-
(item) => item.position == SpecialItemPosition.prepend,
69-
)
70-
.toList(),
71-
appendSpecialItems = specialItems
72-
.where(
73-
(item) => item.position == SpecialItemPosition.append,
74-
)
75-
.toList() {
72+
defaultThemeColorWeChat {
7673
Singleton.textDelegate =
7774
textDelegate ?? assetPickerTextDelegateFromLocale(locale);
7875
}
@@ -141,14 +138,6 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
141138
final AssetsChangeRefreshPredicate<AssetPathEntity>?
142139
assetsChangeRefreshPredicate;
143140

144-
/// List of prepend special items.
145-
/// 前置自定义item列表
146-
final List<SpecialItem<Path>> prependSpecialItems;
147-
148-
/// List of append special items.
149-
/// 附加自定义item列表
150-
final List<SpecialItem<Path>> appendSpecialItems;
151-
152141
/// [ThemeData] for the picker.
153142
/// 选择器使用的主题
154143
ThemeData get theme => pickerTheme ?? AssetPicker.themeData(themeColor);
@@ -341,6 +330,7 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
341330
int? findChildIndexBuilder({
342331
required String id,
343332
required List<Asset> assets,
333+
required List<SpecialItemResult> prependSpecialItemResults,
344334
int placeholderCount = 0,
345335
}) =>
346336
null;
@@ -368,6 +358,7 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
368358
int index,
369359
Asset asset,
370360
Widget child,
361+
List<SpecialItemResult> prependSpecialItemResults,
371362
);
372363

373364
/// The item builder for audio type of asset.
@@ -1248,24 +1239,28 @@ class DefaultAssetPickerBuilderDelegate
12481239
// First, we need the count of the assets.
12491240
int totalCount = wrapper?.assetCount ?? 0;
12501241

1251-
final List<_SpecialItemModel> specialItemModels = specialItems
1242+
final List<SpecialItemResult> specialItemResults = specialItems
12521243
.map((item) {
1253-
return (
1254-
position: item.position,
1255-
item: item.builder?.call(
1256-
context,
1257-
wrapper?.path,
1258-
totalCount,
1259-
permissionNotifier.value,
1260-
)
1244+
final specialItem = item.builder?.call(
1245+
context,
1246+
wrapper?.path,
1247+
totalCount,
1248+
permissionNotifier.value,
12611249
);
1250+
if (specialItem != null) {
1251+
return SpecialItemResult(
1252+
position: item.position,
1253+
item: specialItem,
1254+
);
1255+
}
1256+
return null;
12621257
})
1263-
.whereType<_SpecialItemModel>()
1258+
.whereType<SpecialItemResult>()
12641259
.toList();
12651260

1266-
totalCount += specialItemModels.length;
1261+
totalCount += specialItemResults.length;
12671262

1268-
if (totalCount == 0 && specialItemModels.isEmpty) {
1263+
if (totalCount == 0 && specialItemResults.isEmpty) {
12691264
return loadingIndicator(context);
12701265
}
12711266
// Then we use the [totalCount] to calculate placeholders we need.
@@ -1305,7 +1300,7 @@ class DefaultAssetPickerBuilderDelegate
13051300
context,
13061301
index,
13071302
assets,
1308-
specialItemModels: specialItemModels,
1303+
specialItemResults: specialItemResults,
13091304
),
13101305
),
13111306
);
@@ -1314,14 +1309,20 @@ class DefaultAssetPickerBuilderDelegate
13141309
context: context,
13151310
assets: assets,
13161311
placeholderCount: placeholderCount,
1317-
specialItemModels: specialItemModels,
1312+
specialItemResults: specialItemResults,
13181313
),
13191314
findChildIndexCallback: (Key? key) {
13201315
if (key is ValueKey<String>) {
13211316
return findChildIndexBuilder(
13221317
id: key.value,
13231318
assets: assets,
13241319
placeholderCount: placeholderCount,
1320+
prependSpecialItemResults: specialItemResults
1321+
.where(
1322+
(item) =>
1323+
item.position == SpecialItemPosition.prepend,
1324+
)
1325+
.toList(),
13251326
);
13261327
}
13271328
return null;
@@ -1424,17 +1425,17 @@ class DefaultAssetPickerBuilderDelegate
14241425
BuildContext context,
14251426
int index,
14261427
List<AssetEntity> currentAssets, {
1427-
List<_SpecialItemModel> specialItemModels = const [],
1428+
List<SpecialItemResult> specialItemResults = const [],
14281429
}) {
14291430
final DefaultAssetPickerProvider p =
14301431
context.read<DefaultAssetPickerProvider>();
14311432
final int length = currentAssets.length;
14321433
final PathWrapper<AssetPathEntity>? currentWrapper = p.currentPath;
14331434
final AssetPathEntity? currentPathEntity = currentWrapper?.path;
14341435

1435-
final prependItems = <_SpecialItemModel>[];
1436-
final appendItems = <_SpecialItemModel>[];
1437-
for (final model in specialItemModels) {
1436+
final prependItems = <SpecialItemResult>[];
1437+
final appendItems = <SpecialItemResult>[];
1438+
for (final model in specialItemResults) {
14381439
switch (model.position) {
14391440
case SpecialItemPosition.prepend:
14401441
prependItems.add(model);
@@ -1445,13 +1446,13 @@ class DefaultAssetPickerBuilderDelegate
14451446

14461447
if (prependItems.isNotEmpty) {
14471448
if (index < prependItems.length) {
1448-
return specialItemModels[index].item;
1449+
return specialItemResults[index].item;
14491450
}
14501451
}
14511452

14521453
if (appendItems.isNotEmpty) {
14531454
if (index >= length + prependItems.length) {
1454-
return specialItemModels[index - length].item;
1455+
return specialItemResults[index - length].item;
14551456
}
14561457
}
14571458

@@ -1486,11 +1487,20 @@ class DefaultAssetPickerBuilderDelegate
14861487
itemBannedIndicator(context, asset),
14871488
],
14881489
);
1489-
return assetGridItemSemanticsBuilder(context, index, asset, content);
1490+
return assetGridItemSemanticsBuilder(
1491+
context,
1492+
index,
1493+
asset,
1494+
content,
1495+
prependItems,
1496+
);
14901497
}
14911498

1492-
int semanticIndex(int index) {
1493-
return index - prependSpecialItems.length;
1499+
int semanticIndex(
1500+
int index,
1501+
List<SpecialItemResult> prependSpecialItemResults,
1502+
) {
1503+
return index - prependSpecialItemResults.length;
14941504
}
14951505

14961506
@override
@@ -1499,6 +1509,7 @@ class DefaultAssetPickerBuilderDelegate
14991509
int index,
15001510
AssetEntity asset,
15011511
Widget child,
1512+
List<SpecialItemResult> prependSpecialItemResults,
15021513
) {
15031514
return ValueListenableBuilder<bool>(
15041515
valueListenable: isSwitchingPath,
@@ -1532,7 +1543,7 @@ class DefaultAssetPickerBuilderDelegate
15321543
focusable: !isSwitchingPath,
15331544
identifier: asset.id,
15341545
label: '${semanticsTextDelegate.semanticTypeLabel(asset.type)}'
1535-
'${semanticIndex(index)}, '
1546+
'${semanticIndex(index, prependSpecialItemResults)}, '
15361547
'${asset.createDateTime.toString().replaceAll('.000', '')}',
15371548
hidden: isSwitchingPath,
15381549
hint: hint,
@@ -1550,7 +1561,7 @@ class DefaultAssetPickerBuilderDelegate
15501561
onLongPressHint: semanticsTextDelegate.sActionPreviewHint,
15511562
selected: isSelected,
15521563
sortKey: OrdinalSortKey(
1553-
semanticIndex(index).toDouble(),
1564+
semanticIndex(index, prependSpecialItemResults).toDouble(),
15541565
name: 'GridItem',
15551566
),
15561567
value: selectedIndex > 0 ? '$selectedIndex' : null,
@@ -1563,7 +1574,7 @@ class DefaultAssetPickerBuilderDelegate
15631574
}
15641575
: null,
15651576
child: IndexedSemantics(
1566-
index: semanticIndex(index),
1577+
index: semanticIndex(index, prependSpecialItemResults),
15671578
child: child,
15681579
),
15691580
),
@@ -1579,10 +1590,11 @@ class DefaultAssetPickerBuilderDelegate
15791590
int findChildIndexBuilder({
15801591
required String id,
15811592
required List<AssetEntity> assets,
1593+
required List<SpecialItemResult> prependSpecialItemResults,
15821594
int placeholderCount = 0,
15831595
}) {
15841596
int index = assets.indexWhere((AssetEntity e) => e.id == id);
1585-
index += prependSpecialItems.length;
1597+
index += prependSpecialItemResults.length;
15861598
index += placeholderCount;
15871599
return index;
15881600
}
@@ -1592,7 +1604,7 @@ class DefaultAssetPickerBuilderDelegate
15921604
required BuildContext context,
15931605
required List<AssetEntity> assets,
15941606
int placeholderCount = 0,
1595-
List<_SpecialItemModel> specialItemModels = const [],
1607+
List<SpecialItemResult> specialItemResults = const [],
15961608
}) {
15971609
final PathWrapper<AssetPathEntity>? currentWrapper = context
15981610
.select<DefaultAssetPickerProvider, PathWrapper<AssetPathEntity>?>(
@@ -1602,17 +1614,17 @@ class DefaultAssetPickerBuilderDelegate
16021614
final int length = assets.length + placeholderCount;
16031615

16041616
// Return 1 if the [specialItem] build something.
1605-
if (currentPathEntity == null && specialItemModels.isNotEmpty) {
1606-
return placeholderCount + specialItemModels.length;
1617+
if (currentPathEntity == null && specialItemResults.isNotEmpty) {
1618+
return placeholderCount + specialItemResults.length;
16071619
}
16081620

16091621
// Return actual length if the current path is all.
16101622
// 如果当前目录是全部内容,则返回实际的内容数量。
1611-
if (currentPathEntity?.isAll != true && specialItemModels.isEmpty) {
1623+
if (currentPathEntity?.isAll != true && specialItemResults.isEmpty) {
16121624
return length;
16131625
}
16141626

1615-
return length + specialItemModels.length;
1627+
return length + specialItemResults.length;
16161628
}
16171629

16181630
@override

0 commit comments

Comments
 (0)