ภาษา: ภาษาอังกฤษ | 中文
ตัวเลือกรูปภาพ (พร้อมวิดีโอและเสียง) สำหรับโครงการกระพือตาม UI ของ WeChat
เวอร์ชัน WeChat ปัจจุบันที่ UI ใช้: 8.0.51 UI Designs จะได้รับการอัปเดตหลังจากการอัปเดต WeChat ในทุกเวลา
หากต้องการถ่ายภาพหรือวิดีโอสำหรับสินทรัพย์โปรดตรวจสอบการใช้งานโดยละเอียดในตัวอย่างและตรงไปที่ wechat_camera_picker แพ็คเกจเป็นส่วนขยายแบบสแตนด์อโลนที่สามารถใช้กับการรวมกันได้
ดูคู่มือการย้ายถิ่นเพื่อเรียนรู้วิธีการโยกย้ายระหว่างการเปลี่ยนแปลงการเปลี่ยนแปลง
แพ็คเกจรับประกันได้ว่าจะทำงานกับ Flutter รุ่นที่เสถียร เท่านั้น เราจะไม่อัปเดตแบบเรียลไทม์เพื่อให้สอดคล้องกับช่องอื่น ๆ ของ Flutter
| 3.0 | 3.3 | 3.7 | 3.10 | 3.13 | 3.16 | |
|---|---|---|---|---|---|---|
| 8.9.0+ | ||||||
| 8.7.0+ | ||||||
| 8.5.0+ | ||||||
| 8.4.0+ | ||||||
| 8.0.0+ | ||||||
| 7.3.0+ |
หากคุณมีข้อผิดพลาด resolve conflict เมื่อเรียกใช้ flutter pub get โปรดใช้ dependency_overrides เพื่อแก้ไข
แพ็คเกจถูกสร้างขึ้นจากแพ็คเกจที่ยอดเยี่ยมเหล่านี้
| ชื่อ | คุณสมบัติ |
|---|---|
| photo_manager | abstractions และการจัดการพื้นฐานสำหรับสินทรัพย์ |
| extended_image | ดูตัวอย่างสินทรัพย์ที่มีพฤติกรรมที่คาดหวัง |
| ผู้ให้บริการ | ช่วยในการจัดการสถานะการโต้ตอบของตัวเลือก |
| วิดีโอ _player | เล่นวิดีโอและเสียงตามลำดับ |
การดำเนินการของพวกเขาควรค่อนข้างเสถียรในแพ็คเกจ หากคุณพบปัญหาใด ๆ ที่เกี่ยวข้องกับพวกเขาเมื่อใช้ตัวเลือกให้ส่งปัญหาไปยังตัวติดตามปัญหาของเราก่อน
AssetEntity ด้วยข้อมูลแบบฟอร์มhttpdioRecent เป็นคนอื่น ๆ )AssetEntity จาก File หรือ Uint8List (rawdata)ThemeDataentity.file หรือ AssetEntityImage สำหรับพวกเขาเมื่อแสดง| ชื่อ | ผับ | คนอื่น ๆ |
|---|---|---|
| Insta_assets_picker |
![]() | ![]() | ![]() |
|---|---|---|
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
ระวังประกาศด้านล่างก่อนที่คุณจะเริ่มอะไร:
AssetEntityAssetPathEntityเมื่อคุณมีคำถามเกี่ยวกับ API และพฤติกรรมที่เกี่ยวข้องให้ตรวจสอบเอกสาร API ของ Photo_Manager สำหรับรายละเอียดเพิ่มเติม
การใช้งานส่วนใหญ่มีรายละเอียดครอบคลุมโดยตัวอย่าง โปรดเดินผ่านตัวอย่างอย่างรอบคอบก่อนที่คุณจะมีคำถามใด ๆ
Run flutter pub add wechat_assets_picker หรือเพิ่ม wechat_assets_picker ไปยัง pubspec.yaml การพึ่งพาด้วยตนเอง
dependencies :
wechat_assets_picker : ^latest_versionเวอร์ชัน ที่เสถียร ล่าสุดคือ:
รุ่น dev ล่าสุดคือ:
จากนั้นนำเข้าแพ็คเกจในรหัสของคุณ:
import 'package:wechat_assets_picker/wechat_assets_picker.dart' ; เมื่อใช้แพ็คเกจโปรดอัพเกรด targetSdkVersion และ compileSdkVersion เป็น 33 มิฉะนั้นจะไม่สามารถนำสินทรัพย์บน Android 13 ได้
| ชื่อ | ที่จำเป็น | ที่ประกาศแล้ว | ระดับ API สูงสุด | คนอื่น |
|---|---|---|---|---|
READ_EXTERNAL_STORAGE | ใช่ | ใช่ | 32 | |
WRITE_EXTERNAL_STORAGE | เลขที่ | เลขที่ | 29 | |
ACCESS_MEDIA_LOCATION | ใช่* | เลขที่ | N/A | จำเป็นเมื่ออ่าน exif |
READ_MEDIA_IMAGES | ใช่* | ใช่ | N/A | จำเป็นเมื่ออ่านภาพ |
READ_MEDIA_VIDEO | ใช่* | ใช่ | N/A | จำเป็นเมื่ออ่านวิดีโอ |
READ_MEDIA_AUDIO | ใช่* | ใช่ | N/A | จำเป็นเมื่ออ่านเสียง |
หากคุณกำลังกำหนดเป้าหมาย Android SDK 33+ และคุณไม่จำเป็นต้องโหลดรูปภาพวิดีโอหรือเสียงให้พิจารณาประกาศอนุญาตเฉพาะในแอพของคุณโดยเฉพาะ: โดยเฉพาะ:
< manifest xmlns : android = " http://schemas.android.com/apk/res/android "
xmlns : tools = " http://schemas.android.com/tools "
package = " com.your.app " >
<!-- Requesting access to images and videos. -->
< uses-permission android : name = " android.permission.READ_MEDIA_IMAGES " />
< uses-permission android : name = " android.permission.READ_MEDIA_VIDEO " />
<!-- When your app has no need to access audio, remove it or comment it out. -->
<!-- <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> -->
</ manifest >ios/Podfile และอัปเดตตามนั้น platform :ios, '11.0'
# Heading หากบรรทัดเริ่มต้นด้วยInfo.plist <key>NSPhotoLibraryUsageDescription</key>
<string>Replace with your permission description.</string>
macos/Podfile และอัปเดตตามนั้น platform :osx , '10.15'# Heading หากบรรทัดเริ่มต้นด้วยmacos/Runner.xcworkspaceInfo.plist ตามนั้น เมื่อคุณเลือกสินทรัพย์แพ็คเกจจะได้รับ Locale? จาก BuildContext ของคุณและส่งคืนตัวแทนข้อความที่เกี่ยวข้องของภาษาปัจจุบัน ตรวจสอบให้แน่ใจว่าคุณมี Locale ที่ถูกต้องในทรีวิดเจ็ตของคุณที่สามารถเข้าถึงได้จาก BuildContext มิฉะนั้นจะมีการใช้ตัวแทนจีนเริ่มต้น
ภาษาที่ได้รับมอบหมายจากข้อความคือ:
หากคุณต้องการใช้ตัวแทนข้อความที่กำหนดเอง/คงที่ให้ผ่านมันผ่าน AssetPickerConfig.textDelegate
final List < AssetEntity > ? result = await AssetPicker . pickAssets (context); ใช้ AssetPickerConfig สำหรับพฤติกรรมการเลือกมากขึ้น
final List < AssetEntity > ? result = await AssetPicker . pickAssets (
context,
pickerConfig : const AssetPickerConfig (),
); ฟิลด์ใน AssetPickerConfig :
| ชื่อ | พิมพ์ | คำอธิบาย | ค่าเริ่มต้น |
|---|---|---|---|
| Selectedassets | List<AssetEntity>? | สินทรัพย์ที่เลือก ป้องกันการเลือกที่ซ้ำกัน | null |
| maxassets | int | สินทรัพย์สูงสุดที่ตัวเลือกสามารถเลือกได้ | 9 |
| ทำให้เป็นหน้าเว็บ | int? | จำนวนสินทรัพย์ต่อหน้า ต้องเป็น gridCount หลายตัว | 80 |
| gridthumbnailsize | ThumbnailSize | ขนาดขนาดย่อสำหรับรายการของกริด | ThumbnailSize.square(200) |
| paththumbnailsize | ThumbnailSize | ขนาดย่อสำหรับตัวเลือกเส้นทาง | ThumbnailSize.square(80) |
| previewthumbnailsize | ThumbnailSize? | ดูตัวอย่างขนาดภาพขนาดย่อในผู้ชม | null |
| requestType | RequestType | ประเภทคำขอสำหรับตัวเลือก | RequestType.common |
| SpecialPickerType | SpecialPickerType? | ให้ตัวเลือกในการรวมประเภทตัวเลือกที่กำหนดเอง | null |
| Keepscrolloffset | bool | ไม่ว่าตัวเลือกควรบันทึกการชดเชยการเลื่อนระหว่างการกดและป๊อป | null |
| SortPathDelegate | SortPathDelegate<AssetPathEntity>? | PATH entities จัดเรียงตัวแทนสำหรับตัวเลือกการจัดเรียงเส้นทางตามที่คุณต้องการ | CommonSortPathDelegate |
| SortPathsByModifiedDate | bool | ไม่ว่าจะอนุญาตให้ผู้เข้าร่วมการจัดเรียงเส้นทางด้วย FilterOptionGroup.containsPathModified | false |
| ตัวกรอง | PMFilter? | อนุญาตให้ผู้ใช้ปรับแต่งตัวเลือกตัวกรองสินทรัพย์ | null |
| gridcount | int | จำนวนกริดในตัวเลือก | 4 |
| สีธีม | Color? | สีธีมหลักสำหรับตัวเลือก | Color(0xff00bc56) |
| ผู้เลือก | ThemeData? | ผู้ให้บริการข้อมูลชุดรูปแบบสำหรับตัวเลือกและผู้ชม | null |
| TextDelegate | AssetPickerTextDelegate? | ผู้แทนข้อความสำหรับตัวเลือกเพื่อปรับแต่งข้อความ | AssetPickerTextDelegate() |
| การจัดพิเศษ | SpecialItemPosition | อนุญาตให้ผู้ใช้ตั้งค่ารายการพิเศษในตัวเลือกที่มีหลายตำแหน่ง | SpecialItemPosition.none |
| พิเศษ | SpecialItemBuilder? | ตัวสร้างวิดเจ็ตสำหรับรายการพิเศษ | null |
| LoadingIndicatorBuilder | IndicatorBuilder? | ระบุสถานะการโหลดสำหรับผู้สร้าง | null |
| SelectPredicate | AssetSelectPredicate | เพรดิเคตไม่ว่าจะสามารถเลือกหรือไม่ได้เลือกสินทรัพย์ | null |
| ควร | bool? | ไม่ว่าจะเป็นกริดสินทรัพย์หรือไม่ | null |
| LimitedPermissionOverlayPredicate | LimitedPermissionOverlayPredicate? | แสดงว่าควรแสดงการซ้อนทับการอนุญาตที่ จำกัด หรือไม่ | null |
| Pathnamebuilder | PathNameBuilder<AssetPathEntity>? | สร้างชื่อเส้นทาง (อัลบั้ม) ที่กำหนดเองด้วยเอนทิตีพา ธ ที่กำหนด | null |
| assetschangecallback | AssetsChangeCallback<AssetPathEntity>? | การโทรกลับที่จะถูกเรียกเมื่อระบบแจ้งการเปลี่ยนแปลงสินทรัพย์ | null |
| assetschangerefreshpredicate | AssetsChangeRefreshPredicate<AssetPathEntity>? | ไม่ว่าจะเป็นการเปลี่ยนสินทรัพย์หรือไม่ควรเรียกรีเฟรชด้วยการโทรที่กำหนดและเส้นทางที่เลือกปัจจุบัน | null |
| ควรมีการวิวัฒนาการ | bool | ไม่ว่าจะดูตัวอย่างการเล่นอัตโนมัติหรือไม่ | false |
maxAssets เท่ากับ 1 (โหมดการเลือกเดี่ยว) ให้ใช้ SpecialPickerType.noPreview จะเลือกสินทรัพย์ที่คลิกทันที (กด) โดยผู้ใช้และ poppedlimitedPermissionOverlayPredicate Lives โดยไม่มีการคงอยู่หากคุณต้องการเพิกเฉยต่อตัวอย่างที่ จำกัด หลังจากรีสตาร์ทคุณจะต้องรวมเข้ากับวิธีการออมของคุณเอง เราได้ใช้การใช้งานทั่วไปหลายครั้งกับแพ็คเกจในตัวอย่าง คุณสามารถพบ List<PickMethod> pickMethods ได้ที่นี่และที่นี่ซึ่งให้วิธีการในการเลือกหลายโหมดและโหมดการเก็บเดี่ยว สินทรัพย์จะถูกจัดเก็บชั่วคราวและแสดงที่ด้านล่างของหน้า
AssetEntityImage และ AssetEntityImageProvider สามารถแสดงภาพนิ้วหัวแม่มือของ รูปภาพและวิดีโอ และข้อมูลต้นฉบับของ ภาพ ใช้มันเหมือน Image ทั่วไปและ ImageProvider
AssetEntityImage (asset, isOriginal : false );หรือ:
Image (image : AssetEntityImageProvider (asset, isOriginal : false )); // Register callback.
AssetPicker . registerObserve ();
// Unregister callback.
AssetPicker . unregisterObserve ();AssetEntity ด้วยข้อมูลแบบฟอร์ม มีหลายวิธีในการอัปโหลด AssetEntity ด้วยวิธีการที่เกี่ยวข้องกับ I/O ระวังวิธีการที่เกี่ยวข้องกับ I/O จะใช้ประสิทธิภาพ (โดยทั่วไปแล้วเวลาและหน่วยความจำ) ไม่ควรเรียกบ่อย ๆ
http แพ็คเกจ http : https://pub.dev/packages/http
แพ็คเกจ http ใช้ MultipartFile เพื่อจัดการไฟล์ในคำขอ
รหัสเทียม:
import 'package:http/http.dart' as http;
Future < void > 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 <http. MultipartFile > 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;
}dio แพ็คเกจ dio : https://pub.dev/packages/dio
แพ็คเกจ dio ยังใช้ MultipartFile เพื่อจัดการไฟล์ในคำขอ
รหัสเทียม:
import 'package:dio/dio.dart' as dio;
Future < void > 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 <dio. MultipartFile > 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;
} AssetPickerBuilderDelegate , AssetPickerViewerBuilderDelegate , AssetPickerProvider และ AssetPickerViewerProvider ล้วน แต่ถูกเปิดเผยและเกินจริง คุณสามารถขยายและใช้ประเภทของคุณเองด้วยประเภททั่วไป <A: Asset, P: Path> จากนั้นใช้วิธีนามธรรม
หากต้องการทราบวิธีการปรับแต่งธีมวิดเจ็ตหรือเลย์เอาต์อย่างเต็มที่ ดูวิธีการปรับแต่งผู้ได้รับมอบหมายในหน้าตัวเลือกที่กำหนดเองในตัวอย่าง
คุณสามารถส่ง PRS เพื่อสร้างการใช้งานของคุณเองหากคุณพบว่าการใช้งานของคุณอาจเป็นประโยชน์สำหรับผู้อื่น ดูการใช้งานที่กำหนดเองสำหรับรายละเอียดเพิ่มเติม
Recent เป็นคนอื่น ๆ ) Recent คือชื่ออัลบั้ม Fix สำหรับสินทรัพย์ทั้งหมดบน Android เนื่องจากอัลบั้มทั้งหมดของสินทรัพย์ไม่ใช่อัลบั้มจริง แต่เป็นเพียงบันทึกข้อมูลสื่อทั้งหมดเท่านั้น
ในการแก้ปัญหานั้นบน Android ให้ใช้ pathNameBuilder ตัวอย่างเช่น:
AssetPickerConfig (
pathNameBuilder : ( AssetPathEntity path) => switch (path) {
final p when p.isAll => '最近' ,
// You can apply similar conditions to other common paths.
_ => path.name,
},
) อัลบั้มหรืออัลบั้มอื่น ๆ บนแพลตฟอร์มอื่น ๆ (iOS/MACOS) จะติดตามการแปลระบบที่กำหนดค่าและการแปลที่รองรับ pathNameBuilder พร้อมใช้งานสำหรับทุกอัลบั้ม
ดู photo_manager#561 สำหรับรายละเอียดเพิ่มเติม
AssetEntity จาก File หรือ Uint8List (rawdata) เพื่อรวมแพ็คเกจนี้เข้ากับการถ่ายภาพกล้องหรือสิ่งที่เกี่ยวข้องมีวิธีแก้ปัญหาเกี่ยวกับวิธีการสร้าง AssetEntity ด้วย File หรือวัตถุ Uint8List
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 ข้อสังเกต: หากคุณไม่ต้องการเก็บไฟล์ไว้ในอุปกรณ์ของคุณให้ใช้ File สำหรับการดำเนินการให้มากที่สุด การลบ AssetEntity อาจทำให้ระบบป๊อปอัปแสดง:
final List < String > result = await PhotoManager .editor. deleteWithIds (
< String > [entity.id],
);ดู photo_manager#from-raw-data และ photo_manager#delete-entities สำหรับรายละเอียดเพิ่มเติม
W/Glide (21133): Failed to find GeneratedAppGlideModule.
You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler
in you application ana a @GlideModule annotated AppGlideModule implementation
or LibraryGlideModules will be silently ignored.
Glide ต้องการคำอธิบายประกอบเพื่อรักษา Singleton ป้องกันความขัดแย้งระหว่างอินสแตนซ์และเวอร์ชันดังนั้นในขณะที่ตัวจัดการภาพถ่ายใช้ Glide เพื่อใช้คุณสมบัติภาพโครงการที่นำเข้าสิ่งนี้ควรกำหนด AppGlideModule ของตัวเอง ดู Glide API Docs ที่สร้างขึ้นสำหรับการใช้งาน
ขอบคุณมากสำหรับคนที่ยอดเยี่ยมเหล่านี้ (คีย์อีโมจิ):
Alex Li - - - - ? | Caijinglong - | Marcel Schneider - - | Ganlanshu0211 - - | jasonhezz - | Yaniv เขย่า - - - | Avi-Yadav |
Letalus - - | Greymag - | Nickolay Savchenko - | Kosuke Saigusa - | 三闻书店 | didiosfaust - | Xiejie - |
Ahmed Masoud - | luomo-pro ? | Paigupai - | Muhammad Taqi Abdul Aziz | 何锦余 - | Leon Dudlik - | maël - |
dddrop | เหงียน Phuc Loi - | เซเวอรี่ - | มีชีวิตชีวา - | เอมัส - | Dimil Kalathiya | Gasol Wu - |
โครงการนี้เป็นไปตามข้อกำหนดทั้งหมดของผู้เข้าร่วม การบริจาคทุกชนิดยินดีต้อนรับ !!
ทุกแง่มุมของความคิด Intellij ได้รับการออกแบบมาเพื่อเพิ่มผลผลิตของนักพัฒนา ร่วมกันความช่วยเหลือด้านการเข้ารหัสอัจฉริยะและการออกแบบตามหลักสรีรศาสตร์ทำให้การพัฒนาไม่เพียง แต่มีประสิทธิผล แต่ยังสนุก
ขอบคุณ Jetbrains สำหรับการจัดสรรใบอนุญาตโอเพนซอร์ซฟรีสำหรับ IDEs เช่น Intellij Idea
