### DefaultAssetPickerProvider Example Usage Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/providers.md Example of how to instantiate and use the DefaultAssetPickerProvider. It highlights the provider's responsibilities in managing asset loading and selection. ```dart // Use with DefaultAssetPickerProvider final provider = DefaultAssetPickerProvider( maxAssets: 5, pageSize: 60, selectedAssets: previousSelection, ); // Provider handles: // - Loading paths from photo_manager // - Paginating assets // - Managing selection state // - Thumbnail loading ``` -------------------------------- ### SpecialItem Usage Examples Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/models.md Examples demonstrating how to use SpecialItem with different positions and builders. Use 'prepend' for a camera icon at the top and 'append' for a create button at the bottom. ```dart // Camera icon at top SpecialItem( position: SpecialItemPosition.prepend, builder: cameraBuilder, ) // Create button at bottom SpecialItem( position: SpecialItemPosition.append, builder: createBuilder, ) ``` -------------------------------- ### AssetPickerPageRoute Usage Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/viewer.md Demonstrates how to use `AssetPickerPageRoute` for navigating to the asset picker. The second example shows customization of transition duration and curve. ```dart // Use standard route final result = await Navigator.push>( context, AssetPickerPageRoute( builder: (_) => AssetPicker(...), ), ); // Custom transition final result = await Navigator.push>( context, AssetPickerPageRoute( builder: (_) => AssetPicker(...), transitionDuration: Duration(milliseconds: 400), transitionCurve: Curves.easeOutCubic, ), ); ``` -------------------------------- ### AssetPickerScreen Integration Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/models.md A complete example of an AssetPickerScreen demonstrating the integration of various picker configurations, including custom path name building, special item insertion (camera button), and selection validation. ```dart class AssetPickerScreen extends StatefulWidget { @override State createState() => _AssetPickerScreenState(); } class _AssetPickerScreenState extends State { List selectedAssets = []; Future _pickAssets() async { final result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( maxAssets: 5, selectedAssets: selectedAssets, pathNameBuilder: (path) { // Use PathWrapper if custom sorting if (path.isAll) return 'All Photos'; return path.name.toUpperCase(); }, specialItems: [ // Add camera button SpecialItem( position: SpecialItemPosition.prepend, builder: (context, path, permission) { if (permission == PermissionState.authorized || permission == PermissionState.limited) { return GestureDetector( onTap: () => _openCamera(), child: Container( color: Colors.grey[300], child: Icon(Icons.camera), ), ); } return null; }, ), ], selectPredicate: (context, asset, isSelected) async { // Validate selection if (isSelected && asset.videoDuration > Duration(minutes: 5)) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Video is too long')), ); return false; } return true; }, ), ); if (result != null) { setState(() { selectedAssets = result; }); } } Future _openCamera() async { // Implement camera capture } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Select Photos')), body: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, ), itemCount: selectedAssets.length, itemBuilder: (context, index) { return AssetEntityImage( selectedAssets[index], isOriginal: false, ); }, ), floatingActionButton: FloatingActionButton( onPressed: _pickAssets, child: Icon(Icons.add), ), ); } } ``` -------------------------------- ### Example: SpecialItemBuilder for Camera Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/types.md Example of a SpecialItemBuilder that creates a camera icon. Tapping it opens the camera, and it's positioned at the start of the asset list. ```dart SpecialItemBuilder cameraBuilder = (context, path, permission) { return GestureDetector( onTap: () => openCamera(), child: Container( color: Colors.grey, child: Icon(Icons.camera), ), ); }; SpecialItem( position: SpecialItemPosition.prepend, builder: cameraBuilder, ) ``` -------------------------------- ### Example: LimitedPermissionOverlayPredicate Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/types.md Example of a predicate that shows the limited permission overlay only when the permission state is 'limited'. ```dart LimitedPermissionOverlayPredicate showOverlay = (permission) => permission == PermissionState.limited; AssetPickerConfig( limitedPermissionOverlayPredicate: showOverlay, ) ``` -------------------------------- ### Example: LoadingIndicatorBuilder Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/types.md Example of creating a custom loading indicator that shows a 'No assets' text when the list is empty, otherwise a CircularProgressIndicator. ```dart LoadingIndicatorBuilder myBuilder = (context, isEmpty) { return isEmpty ? Center(child: Text('No assets')) : CircularProgressIndicator(); }; AssetPickerConfig( loadingIndicatorBuilder: myBuilder, ) ``` -------------------------------- ### SpecialItem Camera Button Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/models.md Provides an example of creating a SpecialItem to display a camera button at the beginning of the asset grid, conditionally shown based on permission. ```dart SpecialItem( position: SpecialItemPosition.prepend, builder: (context, path, permission) { if (permission != PermissionState.authorized && permission != PermissionState.limited) { return null; // Hide if no permission } return GestureDetector( onTap: () => openCamera(context), child: Container( color: Colors.grey[300], child: Icon(Icons.camera_alt, size: 40), ), ); }, ) ``` -------------------------------- ### DefaultAssetPickerProvider Initialization and Usage Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/providers.md Initializes the provider with configuration and demonstrates loading paths, switching albums, loading more assets, and getting thumbnails. ```dart final provider = DefaultAssetPickerProvider( maxAssets: 10, requestType: RequestType.image, // Images only selectedAssets: preSelected, ); // Automatically loads paths on first access await provider.getPaths(); // Switch to specific album await provider.switchPath(provider.paths[0]); // Load next page await provider.loadMoreAssets(); // Get thumbnail for path final thumb = await provider.getThumbnailFromPath(pathWrapper); ``` -------------------------------- ### Simple Multi-Select Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/README.md Demonstrates a simple multi-selection of assets and printing their titles. Handles cases where no assets are selected. ```dart final List? assets = await AssetPicker.pickAssets(context); if (assets != null && assets.isNotEmpty) { // Display selected assets for (final asset in assets) { print('Selected: ${asset.title}'); } } ``` -------------------------------- ### Example: AssetSelectPredicate for Confirmation Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/types.md Example of an AssetSelectPredicate that allows selection but shows a confirmation dialog before allowing an asset to be unselected. ```dart AssetSelectPredicate validator = (context, asset, isSelected) async { if (isSelected) { // Allow selection return true; } else { // Show confirmation before unselecting final confirmed = await showDialog( context: context, builder: (ctx) => AlertDialog( title: Text('Unselect?'), actions: [ TextButton( onPressed: () => Navigator.pop(ctx, false), child: Text('Cancel'), ), TextButton( onPressed: () => Navigator.pop(ctx, true), child: Text('Confirm'), ), ], ), ); return confirmed ?? false; } }; AssetPickerConfig( selectPredicate: validator, ) ``` -------------------------------- ### PathWrapper Example Usage Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/models.md Demonstrates how to initialize a PathWrapper and then update it with loaded asset count and thumbnail data using the copyWith method. ```dart // Initial path without metadata final pathWrapper = PathWrapper( path: assetPathEntity, ); // Load asset count final count = await assetPathEntity.assetCountAsync; final updated = pathWrapper.copyWith(assetCount: count); // Load thumbnail final thumb = await firstAsset.thumbnailData; final final updated = updated.copyWith(thumbnailData: thumb); // Now ready to display with count and thumbnail ``` -------------------------------- ### AssetPickerViewerPageRoute Usage Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/viewer.md Shows how to navigate to the asset viewer using `AssetPickerViewerPageRoute`, which applies a fade transition. ```dart final result = await Navigator.push>( context, AssetPickerViewerPageRoute( builder: (_) => AssetPickerViewer(...), ), ); ``` -------------------------------- ### Example: Checking Media Library Permissions Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/delegates.md Demonstrates how to call the permissionCheck method and handle the result or potential errors. Ensure you catch StateError for unauthorized or limited permissions. ```dart try { final permission = await AssetPicker.permissionCheck(); print('Has permission: $permission'); } catch (e) { print('Permission denied'); } ``` -------------------------------- ### Uploading AssetEntity with http.MultipartRequest Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/README.md Upload an `AssetEntity` using the `http` package. This example demonstrates creating a `MultipartRequest` and adding an asset file or bytes to it. Be aware that I/O operations can be performance-intensive. ```dart import 'package:http/http.dart' as http; Future upload() async { final entity = await obtainYourEntity(); final uri = Uri.https('example.com', 'create'); final request = http.MultipartRequest('POST', uri) ..fields['test_field'] = 'test_value' ..files.add(await multipartFileFromAssetEntity(entity)); final response = await request.send(); if (response.statusCode == 200) { print('Uploaded!'); } } Future multipartFileFromAssetEntity(AssetEntity entity) async { http.MultipartFile mf; // Using the file path. final file = await entity.file; if (file == null) { throw StateError('Unable to obtain file of the entity ${entity.id}.'); } mf = await http.MultipartFile.fromPath('test_file', file.path); // Using the bytes. final bytes = await entity.originBytes; if (bytes == null) { throw StateError('Unable to obtain bytes of the entity ${entity.id}.'); } mf = http.MultipartFile.fromBytes('test_file', bytes); return mf; } ``` -------------------------------- ### SpecialItem Create Album Button Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/models.md Illustrates creating a SpecialItem for a 'Create Album' button at the end of the asset grid, using a GestureDetector and BoxDecoration for styling. ```dart SpecialItem( position: SpecialItemPosition.append, builder: (context, path, permission) { return GestureDetector( onTap: () => createNewAlbum(context), child: Container( decoration: BoxDecoration( border: Border.all(color: Colors.blue), ), child: Center( child: Icon(Icons.add, color: Colors.blue), ), ), ); }, ) ``` -------------------------------- ### pickAssetsWithDelegate Usage Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/api-reference.md Example of using pickAssetsWithDelegate with custom provider and builder delegate classes. Requires defining CustomProvider and CustomBuilder. ```dart class CustomProvider extends AssetPickerProvider { // Implementation } class CustomBuilder extends AssetPickerBuilderDelegate { // Implementation } final result = await AssetPicker.pickAssetsWithDelegate( context, delegate: CustomBuilder( initialPermission: PermissionState.authorized, ), ); ``` -------------------------------- ### Calculating pageSize for gridCount Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/errors.md Provides a calculation example to determine the correct `pageSize` when it must be a multiple of `gridCount`, ensuring proper asset distribution. ```dart // Calculate correct pageSize for gridCount final gridCount = 3; final itemsPerPage = 27; // Total items per page final pageSize = (itemsPerPage / gridCount).ceil() * gridCount; // Rounds up to 27 ``` -------------------------------- ### Custom Asset Viewer Builder Implementation Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/delegates.md Example of extending AssetPickerViewerBuilderDelegate to build a custom asset preview viewer. This includes overriding methods for building the UI, initializing state, disposing resources, handling page changes, and updating the viewer. ```dart class CustomViewerBuilder extends AssetPickerViewerBuilderDelegate> { CustomViewerBuilder({ required List previewAssets, required ThemeData themeData, required int currentIndex, }) : super( previewAssets: previewAssets, themeData: themeData, currentIndex: currentIndex, ); @override Widget build(BuildContext context) { return Scaffold( body: PageView( controller: pageController, children: previewAssets.map((asset) => AssetEntityImage(asset) ).toList(), ), ); } @override void initState(State state) { } @override void dispose() { pageController.dispose(); pageStreamController.close(); previewingListController.dispose(); } @override void onPageChanged(int index) { currentIndex = index; pageStreamController.add(index); } @override void didUpdateViewer(state, oldWidget, newWidget) { } } ``` -------------------------------- ### Custom Asset Picker Builder Implementation Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/delegates.md Example of how to extend AssetPickerBuilderDelegate to create a custom asset picker UI. Override abstract methods like build, initState, dispose, and onAssetsChanged to define custom behavior. ```dart class CustomPickerBuilder extends AssetPickerBuilderDelegate { CustomPickerBuilder({ required PermissionState initialPermission, }) : super(initialPermission: initialPermission); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Pick Assets')), body: Center(child: Text('Custom picker UI')), ); } @override void initState(State state) { // Initialize provider, controllers, etc. } @override void dispose() { // Clean up resources } @override Future onAssetsChanged(MethodCall call, VoidCallback setState) async { // Handle media library changes } } ``` -------------------------------- ### AssetPickerConfig pageSize Assertion Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/errors.md Illustrates invalid `pageSize` configurations that trigger an `AssertionError` in debug mode. `pageSize` must be greater than zero. ```dart // ❌ Invalid AssetPickerConfig(pageSize: 0) // ✅ Valid AssetPickerConfig(pageSize: 80) ``` -------------------------------- ### AssetPickerConfig maxAssets Assertion Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/errors.md Demonstrates invalid configurations for `maxAssets` which will throw an `AssertionError` in debug mode. `maxAssets` must be greater than zero. ```dart // ❌ This throws AssertionError in debug AssetPickerConfig(maxAssets: 0) // ❌ This throws AssertionError in debug AssetPickerConfig(maxAssets: -5) // ✅ Correct AssetPickerConfig(maxAssets: 1) ``` -------------------------------- ### Uploading AssetEntity with dio.Dio and FormData Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/README.md Upload an `AssetEntity` using the `dio` package. This example shows how to use `dio.FormData.fromMap` to include the asset file or bytes in the request. I/O operations should not be called frequently due to performance considerations. ```dart import 'package:dio/dio.dart' as dio; Future upload() async { final entity = await obtainYourEntity(); final uri = Uri.https('example.com', 'create'); final response = dio.Dio().requestUri( uri, data: dio.FormData.fromMap({ 'test_field': 'test_value', 'test_file': await multipartFileFromAssetEntity(entity), }), ); print('Uploaded!'); } Future multipartFileFromAssetEntity(AssetEntity entity) async { dio.MultipartFile mf; // Using the file path. final file = await entity.file; if (file == null) { throw StateError('Unable to obtain file of the entity ${entity.id}.'); } mf = await dio.MultipartFile.fromFile(file.path); // Using the bytes. final bytes = await entity.originBytes; if (bytes == null) { throw StateError('Unable to obtain bytes of the entity ${entity.id}.'); } mf = dio.MultipartFile.fromBytes(bytes); return mf; } ``` -------------------------------- ### Validate Assets in selectPredicate with Try-Catch Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/errors.md Shows how to implement validation logic within the selectPredicate callback, using a try-catch block to handle potential errors during validation. This example specifically checks video duration. ```dart selectPredicate: (context, asset, isSelected) async { try { if (isSelected) { // Validate before selecting if (asset.type == AssetType.video) { final duration = asset.videoDuration; if (duration > Duration(minutes: 10)) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Video too long')), ); return false; } } } return true; } catch (e) { print('Validation error: $e'); return false; } } ``` -------------------------------- ### Key Exports: Entry Points Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/INDEX.md Demonstrates the primary methods for initiating asset picking and viewing within the package. ```dart `AssetPicker.pickAssets()` — Basic multi-select picker `AssetPicker.pickAssetsWithDelegate()` — Custom picker `AssetPickerViewer.pushToViewer()` — Asset preview ``` -------------------------------- ### DefaultAssetPickerProvider Configuration and Lifecycle Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/providers.md Demonstrates creating, configuring, listening to changes, and disposing of the DefaultAssetPickerProvider. ```dart // Create and configure final provider = DefaultAssetPickerProvider( maxAssets: 8, pageSize: 100, requestType: RequestType.image, sortPathDelegate: CommonSortPathDelegate(), ); // Load data await provider.getPaths(); print('Loaded ${provider.paths.length} albums'); // Listen for changes provider.addListener(() { print('Selection changed: ${provider.selectedCount} selected'); }); // Clean up provider.dispose(); ``` -------------------------------- ### Basic Asset Picking Usage Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/exports.md Shows fundamental methods for picking assets and configuring the picker. Imports the main package. ```dart import 'package:wechat_assets_picker/wechat_assets_picker.dart'; // Use main exports AssetPicker.pickAssets(context) AssetPickerConfig(maxAssets: 5) SpecialPickerType.wechatMoment AssetEntityImage(asset) ``` -------------------------------- ### Pick Assets with Default Configuration Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/README.md This snippet demonstrates the simplest way to pick assets. It uses the default configuration for the asset picker. ```dart final List? result = await AssetPicker.pickAssets(context); ``` -------------------------------- ### Generic Type Updates for AssetPicker and AssetPickerViewer Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/guides/migration_guide.md Before and after examples of generic type usage in pickAssetsWithDelegate and pushToViewerWithDelegate. ```dart // AssetPicker.pickAssetsWithDelegate static Future?> pickAssetsWithDelegate>( BuildContext context, { required AssetPickerBuilderDelegate delegate, }); // AssetPickerViewer.pushToViewerWithDelegate static Future?> pushToViewerWithDelegate( BuildContext context, { required AssetPickerViewerBuilderDelegate delegate, }); ``` ```dart // AssetPicker.pickAssetsWithDelegate static Future?> pickAssetsWithDelegate< Asset, Path, PickerProvider extends AssetPickerProvider, Delegate extends AssetPickerBuilderDelegate>( BuildContext context, { required Delegate delegate, }); // AssetPickerViewer.pushToViewerWithDelegate static Future?> pushToViewerWithDelegate< Asset, Path, Provider extends AssetPickerViewerProvider, Delegate extends AssetPickerViewerBuilderDelegate>( BuildContext context, { required Delegate delegate, }); ``` -------------------------------- ### Simple pickAssets Usage Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/api-reference.md Demonstrates the basic usage of the pickAssets method to select assets with default settings. ```dart // Simple usage final List? result = await AssetPicker.pickAssets(context); ``` -------------------------------- ### Advanced Customization with Delegates and Providers Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/exports.md Illustrates how to extend asset picking functionality using custom builders and providers. Imports the main package. ```dart import 'package:wechat_assets_picker/wechat_assets_picker.dart'; // Use delegates and providers class MyBuilder extends AssetPickerBuilderDelegate { // ... } class MyProvider extends AssetPickerProvider { // ... } ``` -------------------------------- ### Hidden Export Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/exports.md Demonstrates how to hide specific exports from a Dart file using the 'hide' keyword. ```dart export 'src/constants/constants.dart' hide packageName; ``` -------------------------------- ### Get Thumbnail Data Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/README.md Obtains the thumbnail data for an asset. This data can be used to display a preview image. ```dart final bytes = await asset.thumbnailData; if (bytes != null) { final image = Image.memory(bytes); } ``` -------------------------------- ### AssetPickerViewerProvider with Initial Selection Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/providers.md Shows how to initialize AssetPickerViewerProvider with an initial list of selected assets and listen for changes. ```dart // Create with initial selection final viewerProvider = AssetPickerViewerProvider( initialSelection, maxAssets: 5, ); // Listen for viewer selection changes viewerProvider.addListener(() { print('Viewer selection: ${viewerProvider.currentlySelectedAssets}'); }); // Access final results final final results = viewerProvider.currentlySelectedAssets; ``` -------------------------------- ### Get Video Duration Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/README.md Retrieves the duration of a video asset in seconds. Useful for displaying video playback information. ```dart final duration = asset.videoDuration; print('Duration: ${duration.inSeconds} seconds'); ``` -------------------------------- ### Get Origin Image Bytes Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/README.md Fetches the original bytes of an image asset. These bytes can be used for uploads or further processing. ```dart final bytes = await asset.originBytes; if (bytes != null) { // Use bytes for upload, processing, etc. } ``` -------------------------------- ### Get File Path from Asset Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/README.md Retrieves the file path for a selected asset. The path can be null if the file is not available. ```dart final asset = selectedAssets.first; final file = await asset.file; print(file?.path); ``` -------------------------------- ### Asset Access Best Practices Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/INDEX.md Guidelines for accessing assets, including checking for nullability when retrieving file or byte data, handling potential exceptions from the photo_manager package, and optimizing memory usage by utilizing thumbnail sizes. ```dart // ✓ Check nullability when getting file/bytes // ✓ Handle photo_manager exceptions // ✓ Use thumbnail sizes to reduce memory ``` -------------------------------- ### AssetPickerConfig gridCount Assertion Example Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/errors.md Shows invalid `gridCount` settings that result in an `AssertionError` during debug builds. `gridCount` must be a positive integer. ```dart // ❌ Invalid AssetPickerConfig(gridCount: 0) // ✅ Valid AssetPickerConfig(gridCount: 4) ``` -------------------------------- ### Key Exports: Configuration Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/INDEX.md Highlights the main configuration class for customizing the asset picker's behavior. ```dart `AssetPickerConfig` — Configure picker behavior ``` -------------------------------- ### Push to Viewer with Default Builder Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/viewer.md Navigates to the asset preview screen using the default builder. Ensure previewAssets is not empty to avoid StateError. ```dart final selectedAssets = [/* current selection */]; final allAssets = [/* all assets in path */]; final result = await AssetPickerViewer.pushToViewer( context, previewAssets: allAssets, themeData: theme, selectedAssets: selectedAssets, maxAssets: 5, currentIndex: allAssets.indexOf(selectedAssets.first), ); if (result != null) { setState(() { selectedAssets = result; }); } ``` -------------------------------- ### Builder Package Import Options Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/exports.md Demonstrates two ways to import from the builder module: the main builder export or specific builders. ```dart import 'package:wechat_assets_picker/builder.dart'; // OR import 'package:wechat_assets_picker/src/widget/builder/image_page_builder.dart'; ``` -------------------------------- ### AssetPickerViewer.pushToViewer Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/viewer.md Navigates to the asset preview screen using the default builder. This method allows users to preview a list of assets and potentially update their selection. ```APIDOC ## AssetPickerViewer.pushToViewer ### Description Navigate to asset preview screen with default builder. ### Method static Future?> pushToViewer ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **context** (`BuildContext`) - Required - Build context - **currentIndex** (`int`) - Optional - Starting asset index - **previewAssets** (`List`) - Required - Assets to preview - **themeData** (`ThemeData`) - Required - Theme for viewer - **selectorProvider** (`P?`) - Optional - Selector provider for selection limits - **previewThumbnailSize** (`ThumbnailSize?`) - Optional - Thumbnail size (null = original) - **selectedAssets** (`List?`) - Optional - Currently selected assets - **specialPickerType** (`SpecialPickerType?`) - Optional - Special mode (if any) - **maxAssets** (`int?`) - Optional - Max selectable count - **shouldReversePreview** (`bool`) - Optional - Reverse preview order - **selectPredicate** (`AssetSelectPredicate?`) - Optional - Selection validator - **shouldAutoplayPreview** (`bool`) - Optional - Auto-play videos - **enableLivePhoto** (`bool`) - Optional - Live Photo support - **useRootNavigator** (`bool`) - Optional - Use root navigator - **pageRouteSettings** (`RouteSettings?`) - Optional - Route settings - **pageRouteBuilder** (`AssetPickerViewerPageRouteBuilder>?`) - Optional - Custom route builder ### Returns `Future?>` — Updated selection or null if cancelled. ### Throws - `StateError`: If previewAssets is empty. ### Request Example ```dart final selectedAssets = [/* current selection */]; final allAssets = [/* all assets in path */]; final result = await AssetPickerViewer.pushToViewer( context, previewAssets: allAssets, themeData: theme, selectedAssets: selectedAssets, maxAssets: 5, currentIndex: allAssets.indexOf(selectedAssets.first), ); if (result != null) { setState(() { selectedAssets = result; }); } ``` ``` -------------------------------- ### Custom Loading Indicator Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/configuration.md Provide a custom widget for the loading indicator using `loadingIndicatorBuilder`. This example shows a 'No assets found' message when the list is empty. ```dart final result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( loadingIndicatorBuilder: (context, isAssetsEmpty) { return isAssetsEmpty ? Center(child: Text('No assets found')) : SizedBox.shrink(); }, ), ); ``` -------------------------------- ### pickAssets with Configuration Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/api-reference.md Shows how to use pickAssets with a custom AssetPickerConfig to specify parameters like maxAssets, gridCount, and requestType. ```dart // With configuration final List? result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( maxAssets: 5, gridCount: 4, requestType: RequestType.common, ), ); ``` -------------------------------- ### Custom Asset Selection Validation Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/configuration.md Implement custom validation logic using `selectPredicate` to control which assets can be selected. This example prevents selecting videos longer than 5 minutes. ```dart final result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( selectPredicate: (context, asset, isSelected) async { // Custom validation logic if (asset.videoDuration > Duration(minutes: 5)) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(text: 'Video too long'), ); return false; } return true; }, ), ); ``` -------------------------------- ### Catching StateError for Empty Preview Assets Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/errors.md Catch `StateError` when attempting to preview empty assets. This example checks the error message to specifically identify and handle the 'Previewing empty assets' case. ```dart try { final result = await AssetPickerViewer.pushToViewer( context, previewAssets: assets, themeData: theme, ); } on StateError catch (e) { if (e.message.contains('Previewing empty assets')) { print('Cannot preview empty list'); } } ``` -------------------------------- ### AssetPickerViewerProvider Initialization and Usage Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/providers.md Initializes the viewer provider with selected assets and max count, demonstrating asset selection, deselection, and checking selection status. ```dart final provider = AssetPickerViewerProvider( selectedAssets, maxAssets: 5, ); // Select additional asset provider.selectAsset(newAsset); // Deselect provider.unSelectAsset(asset); // Check selection if (provider.isSelectedNotEmpty) { final count = provider.currentlySelectedAssets.length; print('Selected $count assets'); } // Get results final results = provider.currentlySelectedAssets; ``` -------------------------------- ### AssetsChangeCallback Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/types.md A typedef for listening to system media library changes. It receives permission state, method call details, and the affected path. ```APIDOC ## Typedef: AssetsChangeCallback Listens to system media library changes. ```dart typedef AssetsChangeCallback = void Function( PermissionState permission, MethodCall call, Path? path, ); ``` **Parameters:** - `permission`: Current permission state - `call`: Method call from platform - `path`: Affected path, null for global changes **Example:** ```dart AssetsChangeCallback onChange = (permission, call, path) { print('Method: ${call.method}'); print('Path: ${path?.name}'); }; AssetPickerConfig( assetsChangeCallback: onChange, ) ``` ``` -------------------------------- ### SortPathDelegate Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/delegates.md A delegate for customizing the sorting logic of asset paths (albums). Implement this class to define how albums are ordered, for example, by name, date, or custom criteria. The `sort` method modifies the list of paths in-place. ```APIDOC ## Abstract Class: SortPathDelegate Custom path/album sorting logic. ### Methods - `sort(List> list)` - Sort the path list in-place ### Example ```dart class CustomSortDelegate extends SortPathDelegate { @override void sort(List> list) { // Sort by name list.sort((a, b) => a.path.name.compareTo(b.path.name)); } } AssetPickerConfig( sortPathDelegate: CustomSortDelegate(), ) ``` ``` -------------------------------- ### Permission Check and Pick Assets Signature Changes Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/guides/migration_guide.md Demonstrates the 'Before' and 'After' signatures for permission checking and asset picking methods, including the addition of PermissionRequestOption. ```dart 1. ```dart AssetPicker.permissionCheck(); ``` 2. ```dart Future permissionCheck(); ``` 3. ```dart Future?> pickAssetsWithDelegate>( BuildContext context, { required AssetPickerBuilderDelegate delegate, Key? key, bool useRootNavigator = true, AssetPickerPageRouteBuilder>? pageRouteBuilder, } ) ``` ``` ```dart 1. ```dart AssetPicker.permissionCheck(requestOption: ...); ``` 2. ```dart Future permissionCheck({ PermissionRequestOption requestOption = const PermissionRequestOption, }); ``` 3. ```dart Future?> pickAssetsWithDelegate>( BuildContext context, { required AssetPickerBuilderDelegate delegate, PermissionRequestOption requestOption = const PermissionRequestOption, Key? key, bool useRootNavigator = true, AssetPickerPageRouteBuilder>? pageRouteBuilder, } ) ``` ``` -------------------------------- ### Define Custom Sort Path Delegate Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/delegates.md Implement SortPathDelegate to customize the order of asset paths (albums). Override the 'sort' method to define your custom sorting logic, for example, sorting alphabetically by path name. ```dart abstract class SortPathDelegate { const SortPathDelegate(); void sort(List> list); } ``` ```dart /// Sort the path list in-place void sort(List> list) ``` ```dart /// Default sorting: "All" > "Camera" > "Screenshots" > others (by date) class CommonSortPathDelegate extends SortPathDelegate { const CommonSortPathDelegate(); @override void sort(List> list) { ... } } ``` ```dart class CustomSortDelegate extends SortPathDelegate { @override void sort(List> list) { // Sort by name list.sort((a, b) => a.path.name.compareTo(b.path.name)); } } AssetPickerConfig( sortPathDelegate: CustomSortDelegate(), ) ``` -------------------------------- ### Basic Asset Picking Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/README.md Import and use the main picker widget for basic asset selection. Returns a list of AssetEntity or null. ```dart import 'package:wechat_assets_picker/wechat_assets_picker.dart'; // Basic usage final List? result = await AssetPicker.pickAssets(context); ``` -------------------------------- ### Basic AssetPickerConfig Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/configuration.md Use the default configuration for AssetPicker.pickAssets(). ```dart final result = await AssetPicker.pickAssets( context, pickerConfig: const AssetPickerConfig(), ); ``` -------------------------------- ### Picker Flow Diagram Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/README.md Illustrates the sequence of events from user interaction to asset return in the picker. ```mermaid graph TD UserTapsPick[User taps "Pick"] AssetPickerPickAssets[AssetPicker.pickAssets()] PermissionCheck[Permission Check (AssetPickerDelegate)] LoadPathsAssets[DefaultAssetPickerProvider loads paths/assets] BuildUI[DefaultAssetPickerBuilderDelegate builds UI] UserSelectsAssets[User selects assets] AssetPickerViewerPush[AssetPickerViewer.pushToViewer() (optional preview)] ReturnList[Return List] UserTapsPick --> AssetPickerPickAssets AssetPickerPickAssets --> PermissionCheck PermissionCheck --> LoadPathsAssets LoadPathsAssets --> BuildUI BuildUI --> UserSelectsAssets UserSelectsAssets --> AssetPickerViewerPush AssetPickerViewerPush --> ReturnList ``` -------------------------------- ### Pick Assets with Custom Configuration Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/README.md This snippet shows how to pick assets with custom configurations using AssetPickerConfig. This allows for more control over the picking process. ```dart final List? result = await AssetPicker.pickAssets( context, pickerConfig: const AssetPickerConfig(), ); ``` -------------------------------- ### Listen to Media Changes Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/configuration.md Use `assetsChangeCallback` to react to changes in the media library and `assetsChangeRefreshPredicate` to control when a refresh should occur. ```dart final result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( assetsChangeCallback: (permission, call, path) { print('Media library changed: $call'); }, assetsChangeRefreshPredicate: (permission, call, path) { // Return true to refresh on this change return path == null; // Only refresh if on "All" path }, ), ); ``` -------------------------------- ### File Organization Overview Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/INDEX.md This snippet outlines the directory structure of the wechat_assets_picker package, highlighting the purpose of each key file. ```plaintext output/ ├── README.md # START HERE - Overview & quick start ├── INDEX.md # This file ├── EXPORTS.md # Complete export listing ├── api-reference.md # Main API: AssetPicker class ├── configuration.md # Configuration options: AssetPickerConfig ├── types.md # Type definitions & enumerations ├── delegates.md # Customization: builders, text, sorting ├── providers.md # State management: providers ├── viewer.md # Preview UI: AssetPickerViewer ├── models.md # Data models: PathWrapper, SpecialItem └── errors.md # Errors & validation ``` -------------------------------- ### AssetPickerViewer.pushToViewerWithDelegate Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/viewer.md Navigates to the asset preview screen using a custom delegate, allowing for highly customized UI and behavior during asset review. ```APIDOC ## AssetPickerViewer.pushToViewerWithDelegate ### Description Navigate with custom viewer delegate. ### Method static Future?> pushToViewerWithDelegate ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **context** (`BuildContext`) - Required - Build context - **delegate** (`Delegate`) - Required - Custom builder delegate - **permissionRequestOption** (`PermissionRequestOption`) - Optional - Permission config - **useRootNavigator** (`bool`) - Optional - Use root navigator - **pageRouteSettings** (`RouteSettings?`) - Optional - Route settings - **pageRouteBuilder** (`AssetPickerViewerPageRouteBuilder>?`) - Optional - Custom route builder ### Returns `Future?>` — Selection or null. ### Request Example ```dart class CustomViewerBuilder extends AssetPickerViewerBuilderDelegate<...> { // Custom implementation } final result = await AssetPickerViewer.pushToViewerWithDelegate( context, delegate: CustomViewerBuilder( previewAssets: assets, themeData: theme, currentIndex: 0, ), ); ``` ``` -------------------------------- ### Usage: SpecialItemPosition.prepend Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/types.md Use this to add a custom item at the beginning of the asset list. ```dart SpecialItem( position: SpecialItemPosition.prepend, builder: (context, path, permission) => CustomWidget(), ) ``` -------------------------------- ### Push to Viewer with Custom Delegate Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/viewer.md Navigates to the asset preview screen using a custom builder delegate. This allows for a customized UI and behavior. ```dart class CustomViewerBuilder extends AssetPickerViewerBuilderDelegate<...> { // Custom implementation } final result = await AssetPickerViewer.pushToViewerWithDelegate( context, delegate: CustomViewerBuilder( previewAssets: assets, themeData: theme, currentIndex: 0, ), ); ``` -------------------------------- ### Handle Asset Picker Errors with Try-Catch Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/errors.md Demonstrates how to use a try-catch block to handle potential errors during asset picking, including user cancellation and unexpected exceptions. It shows how to display user feedback via a ScaffoldMessenger. ```dart Future pickAssets() async { try { final result = await AssetPicker.pickAssets(context); if (result != null && result.isNotEmpty) { // Use assets print('Selected ${result.length} assets'); } else { // User cancelled print('Picker cancelled'); } } catch (e) { // Handle unexpected errors print('Picker error: $e'); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error opening picker')), ); } } ``` -------------------------------- ### AssetPickerViewerBuilderDelegate Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/delegates.md Base class for building custom asset preview viewer components. It provides a constructor to initialize viewer state and defines abstract methods for building the viewer widget, initializing state, disposing resources, handling page changes, and updating the viewer. ```APIDOC ## Abstract Class: AssetPickerViewerBuilderDelegate Base class for building asset preview viewer components. **Full Signature:** ```dart abstract class AssetPickerViewerBuilderDelegate> { AssetPickerViewerBuilderDelegate({ required List previewAssets, required ThemeData themeData, required int currentIndex, Provider? provider, List? selectedAssets, int? maxAssets, bool shouldReversePreview = false, AssetSelectPredicate? selectPredicate, }) ``` ### Constructor Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | previewAssets | `List` | Yes | — | Assets to preview | | themeData | `ThemeData` | Yes | — | Theme for viewer | | currentIndex | `int` | Yes | — | Starting asset index | | provider | `Provider?` | No | null | Selection state provider | | selectedAssets | `List?` | No | null | Pre-selected assets | | maxAssets | `int?` | No | null | Maximum selectable | | shouldReversePreview | `bool` | No | false | Reverse preview order | | selectPredicate | `AssetSelectPredicate?` | No | null | Selection validator | ### Key Properties ```dart /// Assets to display in preview final List previewAssets; /// Current viewing index int currentIndex; /// Theme data final ThemeData themeData; /// Selected assets in viewer final List? selectedAssets; /// Maximum selectable count final int? maxAssets; /// Whether previewing reversed final bool shouldReversePreview; /// Current asset being viewed Asset get currentAsset { ... } /// Controller for asset page view ExtendedPageController get pageController; /// Controller for page index stream StreamController pageStreamController; /// Controller for preview scroll ScrollController previewingListController; /// Notifier for detail visibility ValueNotifier isDisplayingDetail; /// Height of bottom preview bar double get bottomPreviewHeight => 90.0; /// Height of bottom action bar double get bottomBarHeight => 50.0; ``` ### Abstract Methods ```dart /// Build the viewer widget Widget build(BuildContext context); /// Initialize state void initState(State state); /// Cleanup resources void dispose(); /// Handle page changes void onPageChanged(int index); /// Handle viewer updates void didUpdateViewer( State state, AssetPickerViewer oldWidget, AssetPickerViewer newWidget, ) ``` **Example:** ```dart class CustomViewerBuilder extends AssetPickerViewerBuilderDelegate> { CustomViewerBuilder({ required List previewAssets, required ThemeData themeData, required int currentIndex, }) : super( previewAssets: previewAssets, themeData: themeData, currentIndex: currentIndex, ); @override Widget build(BuildContext context) { return Scaffold( body: PageView( controller: pageController, children: previewAssets.map((asset) => AssetEntityImage(asset) ).toList(), ), ); } @override void initState(State state) { } @override void dispose() { pageController.dispose(); pageStreamController.close(); previewingListController.dispose(); } @override void onPageChanged(int index) { currentIndex = index; pageStreamController.add(index); } @override void didUpdateViewer(state, oldWidget, newWidget) { } } ``` **Source:** `lib/src/delegates/asset_picker_viewer_builder_delegate.dart` ``` -------------------------------- ### AssetPickerProvider Abstract Methods Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/providers.md These abstract methods define the core functionalities that concrete implementations of AssetPickerProvider must provide, including loading paths, thumbnails, and assets. ```dart /// Load all available paths (albums) Future getPaths(); /// Get thumbnail for a specific path Future getThumbnailFromPath(PathWrapper path); /// Switch to a different path Future switchPath([PathWrapper? path]); /// Load assets from a specific path Future getAssetsFromPath(int page, Path path); /// Load next page of assets Future loadMoreAssets(); ``` -------------------------------- ### Key Exports: Customization Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/INDEX.md Lists the key interfaces and classes available for customizing the UI and functionality of the asset picker. ```dart `AssetPickerBuilderDelegate` — Override UI `AssetPickerProvider` — Override asset loading `AssetPickerTextDelegate` — Translations `SortPathDelegate` — Album ordering `SpecialItem` — Custom grid items ``` -------------------------------- ### Pre-selected Assets with AssetPickerConfig Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/configuration.md Initialize the picker with a list of pre-selected assets and set a new maximum limit. ```dart final previouslySelected = [/* list of AssetEntity */]; final result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( selectedAssets: previouslySelected, maxAssets: 10, ), ); ``` -------------------------------- ### Custom Limits and Grid with AssetPickerConfig Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/configuration.md Configure the maximum number of assets, grid columns, and page size for the asset picker. ```dart final result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( maxAssets: 5, gridCount: 3, pageSize: 60, ), ); ``` -------------------------------- ### AssetPickerProvider Constructor Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/providers.md This is the full signature for the abstract AssetPickerProvider class. It defines the base state management for asset picking. ```dart abstract class AssetPickerProvider extends ChangeNotifier { AssetPickerProvider({ int maxAssets = 9, int pageSize = 80, ThumbnailSize pathThumbnailSize = ThumbnailSize.square(80), List? selectedAssets, }) ``` -------------------------------- ### Key Exports: UI Components Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/INDEX.md Lists the various UI components provided by the package for building the asset picker interface. ```dart `AssetPickerAppBar` — Custom app bar `AssetPickerPageRoute` — Slide transition route `AssetPickerViewerPageRoute` — Fade transition route `AssetEntityImage` — Display assets `ImagePageBuilder`, `VideoPageBuilder`, `AudioPageBuilder` — Media viewers ``` -------------------------------- ### Configuring SpecialItems in AssetPickerConfig Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/_autodocs/models.md Shows how to integrate SpecialItem instances into the AssetPickerConfig to customize the asset grid with elements like a camera button. ```dart final result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( specialItems: [ SpecialItem( position: SpecialItemPosition.prepend, builder: (context, path, permission) { return CameraButtonWidget(); }, ), ], ), ); ``` -------------------------------- ### Create AssetEntity from File or Uint8List Source: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/README.md Use these methods to create an AssetEntity from a File or Uint8List. The image is saved to the device first. Prefer using File operations if you don't need to keep the original data. ```dart final File file = your_file; // Your `File` object final String path = file.path; final AssetEntity fileEntity = await PhotoManager.editor.saveImageWithPath( path, title: basename(path), ); // Saved in the device then create an AssetEntity final Uint8List data = your_data; // Your `Uint8List` object final AssetEntity imageEntity = await PhotoManager.editor.saveImage( file.path, title: 'title_with_extension.jpg', ); // Saved in the device then create an AssetEntity ```