Skip to content

Commit a764a6e

Browse files
committed
Support multiple special items.
1 parent d4bbece commit a764a6e

File tree

6 files changed

+61
-66
lines changed

6 files changed

+61
-66
lines changed

example/lib/constants/picker_method.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ class PickMethod {
137137
selectedAssets: assets,
138138
specialItems: [
139139
SpecialItem(
140-
itemPosition: SpecialItemPosition.prepend,
141-
itemBuilder: (
140+
position: SpecialItemPosition.prepend,
141+
builder: (
142142
BuildContext context,
143143
AssetPathEntity? path,
144144
int length,
@@ -194,8 +194,8 @@ class PickMethod {
194194
selectedAssets: assets,
195195
specialItems: [
196196
SpecialItem(
197-
itemPosition: SpecialItemPosition.prepend,
198-
itemBuilder: (
197+
position: SpecialItemPosition.prepend,
198+
builder: (
199199
BuildContext context,
200200
AssetPathEntity? path,
201201
int length,
@@ -309,8 +309,8 @@ class PickMethod {
309309
selectedAssets: assets,
310310
specialItems: [
311311
SpecialItem(
312-
itemPosition: SpecialItemPosition.prepend,
313-
itemBuilder: (
312+
position: SpecialItemPosition.prepend,
313+
builder: (
314314
BuildContext context,
315315
AssetPathEntity? path,
316316
int length,
@@ -344,8 +344,8 @@ class PickMethod {
344344
selectedAssets: assets,
345345
specialItems: [
346346
SpecialItem(
347-
itemPosition: SpecialItemPosition.prepend,
348-
itemBuilder: (
347+
position: SpecialItemPosition.prepend,
348+
builder: (
349349
BuildContext context,
350350
AssetPathEntity? path,
351351
int length,
@@ -357,8 +357,8 @@ class PickMethod {
357357
},
358358
),
359359
SpecialItem(
360-
itemPosition: SpecialItemPosition.append,
361-
itemBuilder: (
360+
position: SpecialItemPosition.append,
361+
builder: (
362362
BuildContext context,
363363
AssetPathEntity? path,
364364
int length,

example/lib/customs/pickers/directory_file_asset_picker.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,8 +703,8 @@ class FileAssetPickerBuilder
703703
) {
704704
int currentIndex = index;
705705

706-
if (prepandSpecialItems.isNotEmpty) {
707-
currentIndex = index - prepandSpecialItems.length;
706+
if (prependSpecialItems.isNotEmpty) {
707+
currentIndex = index - prependSpecialItems.length;
708708
}
709709

710710
final File asset = currentAssets.elementAt(currentIndex);

example/lib/l10n/gen/app_localizations_zh.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ class AppLocalizationsZh extends AppLocalizations {
9494
String get pickMethodPrependItemDescription => '网格的靠前位置会添加一个自定义的 widget。';
9595

9696
@override
97-
String get pickMethodMultiSpecialItemsName => '多个特殊item';
97+
String get pickMethodMultiSpecialItemsName => '多个特殊 widget';
9898

9999
@override
100100
String get pickMethodMultiSpecialItemsDescription =>
101-
'网格的靠前或靠后位置会添加多个自定义的 widget。';
101+
'网格的靠前或靠后位置会可以多个自定义的 widget。';
102102

103103
@override
104104
String get pickMethodNoPreviewName => '禁止预览';

lib/src/constants/config.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
import 'package:flutter/material.dart';
66
import 'package:photo_manager/photo_manager.dart';
7-
import 'package:wechat_assets_picker/src/models/special_item.dart';
87

98
import '../constants/typedefs.dart';
109
import '../delegates/asset_picker_text_delegate.dart';
1110
import '../delegates/sort_path_delegate.dart';
11+
import '../models/special_item.dart';
1212
import 'constants.dart';
1313
import 'enums.dart';
1414

@@ -193,5 +193,5 @@ class AssetPickerConfig {
193193

194194
/// List of special items.
195195
/// 自定义item列表
196-
final List<SpecialItem> specialItems;
196+
final List<SpecialItem<AssetPathEntity>> specialItems;
197197
}

lib/src/constants/typedefs.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import 'package:flutter/widgets.dart';
99
import 'package:photo_manager/photo_manager.dart' show PermissionState;
1010
import 'package:provider/provider.dart';
1111

12+
import './enums.dart';
13+
1214
/// Mirroring [ChangeNotifierProvider].
1315
typedef CNP<T extends ChangeNotifier?> = ChangeNotifierProvider<T>;
1416

@@ -76,3 +78,8 @@ typedef AssetsChangeRefreshPredicate<Path> = bool Function(
7678
MethodCall call,
7779
Path? path,
7880
);
81+
82+
typedef SpecialItemModel = ({
83+
SpecialItemPosition position,
84+
Widget item,
85+
});

lib/src/delegates/asset_picker_builder_delegate.dart

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,12 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
5757
),
5858
themeColor = pickerTheme?.colorScheme.secondary ??
5959
themeColor ??
60-
defaultThemeColorWeChat {
60+
defaultThemeColorWeChat,
61+
prependSpecialItems = specialItems
62+
.where(
63+
(item) => item.position == SpecialItemPosition.prepend,
64+
)
65+
.toList() {
6166
Singleton.textDelegate =
6267
textDelegate ?? assetPickerTextDelegateFromLocale(locale);
6368
}
@@ -86,7 +91,7 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
8691

8792
/// List of special items.
8893
/// 自定义item列表
89-
final List<SpecialItem> specialItems;
94+
final List<SpecialItem<Path>> specialItems;
9095

9196
/// Indicates the loading status for the builder.
9297
/// 指示目前加载的状态
@@ -126,6 +131,10 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
126131
final AssetsChangeRefreshPredicate<AssetPathEntity>?
127132
assetsChangeRefreshPredicate;
128133

134+
/// List of prepend special items.
135+
/// 前置自定义item列表
136+
final List<SpecialItem<Path>> prependSpecialItems;
137+
129138
/// [ThemeData] for the picker.
130139
/// 选择器使用的主题
131140
ThemeData get theme => pickerTheme ?? AssetPicker.themeData(themeColor);
@@ -220,14 +229,6 @@ abstract class AssetPickerBuilderDelegate<Asset, Path> {
220229
AssetPickerTextDelegate get semanticsTextDelegate =>
221230
Singleton.textDelegate.semanticsTextDelegate;
222231

223-
Iterable<SpecialItem> get prepandSpecialItems => specialItems.where(
224-
(model) => model.itemPosition == SpecialItemPosition.prepend,
225-
);
226-
227-
Iterable<SpecialItem> get appendSpecialItems => specialItems.where(
228-
(model) => model.itemPosition == SpecialItemPosition.append,
229-
);
230-
231232
/// Keep a `initState` method to sync with [State].
232233
/// 保留一个 `initState` 方法与 [State] 同步。
233234
@mustCallSuper
@@ -759,7 +760,7 @@ class DefaultAssetPickerBuilderDelegate
759760
this.specialPickerType,
760761
this.keepScrollOffset = false,
761762
this.shouldAutoplayPreview = false,
762-
this.specialItems = const [],
763+
super.specialItems = const [],
763764
}) {
764765
// Add the listener if [keepScrollOffset] is true.
765766
if (keepScrollOffset) {
@@ -818,11 +819,6 @@ class DefaultAssetPickerBuilderDelegate
818819
/// 预览是否自动播放
819820
final bool shouldAutoplayPreview;
820821

821-
/// List of special items.
822-
/// 自定义item列表
823-
@override
824-
final List<SpecialItem> specialItems;
825-
826822
/// [Duration] when triggering path switching.
827823
/// 切换路径时的动画时长
828824
Duration get switchingPathDuration => const Duration(milliseconds: 300);
@@ -1236,29 +1232,23 @@ class DefaultAssetPickerBuilderDelegate
12361232
builder: (context, wrapper, _) {
12371233
// First, we need the count of the assets.
12381234
int totalCount = wrapper?.assetCount ?? 0;
1239-
final List<
1240-
({SpecialItemPosition specialItemPosition, Widget specialItem})>
1241-
specialItemModels = [];
1242-
// If user chose a special item's position, add 1 count.
1243-
if (specialItems.isNotEmpty) {
1244-
for (final item in specialItems) {
1245-
final specialItem = item.itemBuilder?.call(
1246-
context,
1247-
wrapper?.path,
1248-
totalCount,
1249-
isPermissionLimited,
1250-
);
1251-
if (specialItem != null) {
1252-
specialItemModels.add(
1253-
(
1254-
specialItemPosition: item.itemPosition,
1255-
specialItem: specialItem,
1256-
),
1235+
1236+
final List<SpecialItemModel> specialItemModels = specialItems
1237+
.map((item) {
1238+
return (
1239+
position: item.position,
1240+
item: item.builder?.call(
1241+
context,
1242+
wrapper?.path,
1243+
totalCount,
1244+
isPermissionLimited,
1245+
)
12571246
);
1258-
totalCount += 1;
1259-
}
1260-
}
1261-
}
1247+
})
1248+
.whereType<SpecialItemModel>()
1249+
.toList();
1250+
1251+
totalCount += specialItemModels.length;
12621252

12631253
if (totalCount == 0 && specialItemModels.isEmpty) {
12641254
return loadingIndicator(context);
@@ -1419,8 +1409,7 @@ class DefaultAssetPickerBuilderDelegate
14191409
BuildContext context,
14201410
int index,
14211411
List<AssetEntity> currentAssets, {
1422-
List<({SpecialItemPosition specialItemPosition, Widget specialItem})>
1423-
specialItemModels = const [],
1412+
List<SpecialItemModel> specialItemModels = const [],
14241413
}) {
14251414
final DefaultAssetPickerProvider p =
14261415
context.read<DefaultAssetPickerProvider>();
@@ -1429,22 +1418,22 @@ class DefaultAssetPickerBuilderDelegate
14291418
final AssetPathEntity? currentPathEntity = currentWrapper?.path;
14301419

14311420
final prepandSpecialItemModels = specialItemModels.where(
1432-
(model) => model.specialItemPosition == SpecialItemPosition.prepend,
1421+
(model) => model.position == SpecialItemPosition.prepend,
14331422
);
14341423
final appendSpecialItemModels = specialItemModels.where(
1435-
(model) => model.specialItemPosition == SpecialItemPosition.append,
1424+
(model) => model.position == SpecialItemPosition.append,
14361425
);
14371426

14381427
if (specialItemModels.isNotEmpty) {
14391428
if (prepandSpecialItemModels.isNotEmpty) {
14401429
if (index < prepandSpecialItemModels.length) {
1441-
return specialItemModels[index].specialItem;
1430+
return specialItemModels[index].item;
14421431
}
14431432
}
14441433

14451434
if (appendSpecialItemModels.isNotEmpty) {
14461435
if (index >= length + prepandSpecialItemModels.length) {
1447-
return specialItemModels[index - length].specialItem;
1436+
return specialItemModels[index - length].item;
14481437
}
14491438
}
14501439
}
@@ -1488,8 +1477,8 @@ class DefaultAssetPickerBuilderDelegate
14881477
}
14891478

14901479
int semanticIndex(int index) {
1491-
if (prepandSpecialItems.isNotEmpty) {
1492-
return index - prepandSpecialItems.length + 1;
1480+
if (prependSpecialItems.isNotEmpty) {
1481+
return index - prependSpecialItems.length + 1;
14931482
}
14941483

14951484
return index;
@@ -1584,8 +1573,8 @@ class DefaultAssetPickerBuilderDelegate
15841573
}) {
15851574
int index = assets.indexWhere((AssetEntity e) => e.id == id);
15861575

1587-
if (prepandSpecialItems.isNotEmpty) {
1588-
index += prepandSpecialItems.length;
1576+
if (prependSpecialItems.isNotEmpty) {
1577+
index += prependSpecialItems.length;
15891578
}
15901579
index += placeholderCount;
15911580
return index;
@@ -1596,8 +1585,7 @@ class DefaultAssetPickerBuilderDelegate
15961585
required BuildContext context,
15971586
required List<AssetEntity> assets,
15981587
int placeholderCount = 0,
1599-
List<({SpecialItemPosition specialItemPosition, Widget specialItem})>
1600-
specialItemModels = const [],
1588+
List<SpecialItemModel> specialItemModels = const [],
16011589
}) {
16021590
final PathWrapper<AssetPathEntity>? currentWrapper = context
16031591
.select<DefaultAssetPickerProvider, PathWrapper<AssetPathEntity>?>(

0 commit comments

Comments
 (0)