CachedNetworkImage เป็นวิดเจ็ต Flutter สำหรับโหลดและแคชรูปภาพจากเครือข่ายพร้อมรองรับตัวบ่งชี้ความคืบหน้า ตัวยึดตำแหน่ง และการจัดการข้อผิดพลาด ตามหน้าแพ็คเกจอย่างเป็นทางการ ไลบรารีนี้ใช้ flutter_cache_manager เป็นพื้นฐานและให้การแคชบนดิสก์อัตโนมัติพร้อม TTL ที่ปรับแต่งได้ CachedNetworkImage เป็นโซลูชันมาตรฐานสำหรับการโหลดรูปภาพในแอปพลิเคชัน Flutter พร้อมการแคช
ประเด็นสำคัญ
CachedNetworkImage เป็นวิดเจ็ต Flutter จากแพ็คเกจชื่อเดียวกันบน pub.dev ที่ให้การโหลดรูปภาพจากเครือข่ายพร้อมแคชอัตโนมัติ มันเป็นตัวห่อหุ้มรอบ Image.network มาตรฐาน เพิ่มการแคชไฟล์ ตัวบ่งชี้ความคืบหน้า และการจัดการข้อผิดพลาดแบบกำหนดเอง
ภายใน CachedNetworkImage ใช้ flutter_cache_manager — ตัวจัดการแคชที่มีฐานข้อมูล SQLite สำหรับติดตามไฟล์ ในการร้องขอครั้งแรก รูปภาพจะถูกดาวน์โหลดจากเครือข่าย บันทึกลงดิสก์ และในการร้องขอครั้งถัดไปจะถูกส่งจากแคชโดยคำนึงถึง TTL (ค่าเริ่มต้น 7 วัน) การแคชในหน่วยความจำถูกจัดการโดย ImageCache มาตรฐานของ Flutter
แพ็คเกจนี้มี มากกว่า 4,000 ไลก์ บน pub.dev และถูกใช้ในโปรเจค Flutter นับพัน CachedNetworkImage รองรับทุกแพลตฟอร์มของ Flutter: Android, iOS, Web, macOS, Windows และ Linux ด้วย API ที่เป็นหนึ่งเดียว นักพัฒนาจึงได้รับการโหลดรูปภาพข้ามแพลตฟอร์มโดยไม่ต้องใช้โค้ดเฉพาะแพลตฟอร์ม
Flutter ใช้ระบบแคชสองระดับ: ImageCache (หน่วยความจำ) และ flutter_cache_manager (ดิสก์ + SQLite) ImageCache เป็นแคชรวมของรูปภาพที่ถอดรหัสแล้วโดยมีข้อจำกัดด้านจำนวน (ค่าเริ่มต้น 1000) และขนาด (ค่าเริ่มต้น 100 MB) flutter_cache_manager จัดการไฟล์บนดิสก์และข้อมูลเมตาของไฟล์เหล่านั้น
เมื่อ CachedNetworkImage ได้รับคำขอรูปภาพ มันจะตรวจสอบ ImageCache ของ Flutter ก่อน — หากรูปภาพถูกถอดรหัสในหน่วยความจำแล้ว มันจะแสดงทันที หากไม่พบในแคช ดิสก์จะถูกตรวจสอบผ่าน flutter_cache_manager: คำสั่ง SQLite จะตรวจสอบว่าไฟล์มีอยู่ในแคชและ TTL หมดอายุหรือไม่ หากไฟล์ยังใช้ได้ — มันจะถูกอ่านจากดิสก์ ถอดรหัส และแสดง หากไฟล์หายไปหรือ TTL หมดอายุ — จะทำการร้องขอ HTTP
DefaultCacheManager มีเมธอด emptyCache() (ทำความสะอาดทั้งหมด), cleanCache() (ลบเฉพาะที่หมดอายุ) และ clearCacheWithAge() พร้อมวันที่กำหนดเอง ImageCache จะถูกล้างโดยอัตโนมัติเมื่อหน่วยความจำเหลือน้อยหรือด้วยตนเองผ่าน imageCache.clear()
CachedNetworkImage สร้างขึ้นบนการประกอบวิดเจ็ต Flutter มาตรฐาน การทำงานภายในใช้ ImageProvider สำหรับการโหลดแบบอะซิงโครนัสและ StatefulWidget สำหรับการจัดการวงจรชีวิต
imageUrl — พารามิเตอร์ที่จำเป็น, URL ของรูปภาพ (String หรือ Uri) placeholder — วิดเจ็ตที่แสดงระหว่างการโหลด errorWidget — วิดเจ็ตเมื่อเกิดข้อผิดพลาดในการโหลด progressIndicatorBuilder — builder ที่รับบริบท, URL และ DownloadProgress พร้อมฟิลด์ totalSize และ downloadedSize
CachedNetworkImageProvider — การใช้งาน ImageProvider ที่ส่งคืน CachedNetworkStreamImage ซึ่งจัดการการดาวน์โหลดและการแคช ผู้ให้บริการรวมเข้ากับ ImageCache ของ Flutter และรองรับความสามารถทั้งหมดของ ImageProvider มาตรฐาน: การปรับขนาด การจัดกึ่งกลาง และการทำซ้ำ
flutter_cache_manager เป็นไลบรารีพื้นฐานของระบบแคชของ CachedNetworkImage โดยให้ DefaultCacheManager พร้อมฐานข้อมูล SQLite ที่กำหนดค่าแล้ว TTL และขีดจำกัดไฟล์ หากจำเป็น สามารถสร้าง CacheManager ที่กำหนดเองด้วยพารามิเตอร์เฉพาะได้
| พารามิเตอร์ | คำอธิบาย | ค่าเริ่มต้น |
|---|---|---|
| maxAgeCacheObject | ระยะเวลาจัดเก็บไฟล์สูงสุด | 7 วัน |
| maxNrOfCacheObjects | จำนวนไฟล์สูงสุด | 200 |
| key | ตัวระบุเฉพาะของตัวจัดการ | “default” |
| repo | ประเภทพื้นที่จัดเก็บข้อมูลเมตา | CacheObjectRepository (SQLite) |
| fileService | ไคลเอ็นต์ HTTP สำหรับดาวน์โหลด | HttpFileService |
CacheManager ที่กำหนดเองถูกสร้างขึ้นโดยสืบทอดจาก CacheManager พร้อมการแทนที่เมธอด ซึ่งมีประโยชน์เมื่อจำเป็นต้องเก็บรูปภาพในไดเรกทอรีแยกต่างหากหรือใช้ไคลเอ็นต์ HTTP อื่น จากนั้นอินสแตนซ์ของตัวจัดการจะถูกส่งต่อไปยังพารามิเตอร์ cacheManager ของ CachedNetworkImage
ฐานข้อมูล SQLite ของ DefaultCacheManager อยู่ใน temporaryDirectory ของแอปพลิเคชันที่พาธ `{key}/CacheObjects.db` ประกอบด้วยตาราง cacheObjects พร้อมฟิลด์: key (URL), relativePath, url, creationDate, eTag, httpHeaders เมื่อทำความสะอาดรายการที่หมดอายุ จะใช้คำสั่ง SQL ที่มีเงื่อนไขบน maxAgeCacheObject
CachedNetworkImage มีสองวิธีการโหลดหลัก: วิดเจ็ต CachedNetworkImage และ CachedNetworkImageProvider สำหรับสถานการณ์ที่กำหนดเอง
CachedNetworkImage — วิธีการหลัก เพียงส่ง imageUrl และ placeholder วิดเจ็ตจะแสดงตัวยึดตำแหน่งโดยอัตโนมัติจนกว่าการโหลดจะเสร็จสมบูรณ์แล้วแทนที่ด้วยรูปภาพ
CachedNetworkImage(
imageUrl: "https://example.com/photo.jpg",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
width: 200,
height: 200,
fit: BoxFit.cover,
)
placeholder และ errorWidget เป็นฟังก์ชัน builder ที่รับบริบท, URL และ (สำหรับ errorWidget) ออบเจ็กต์ข้อผิดพลาด วิธีการนี้ช่วยให้แสดงตัวยึดตำแหน่งที่แตกต่างกันขึ้นอยู่กับ URL หรือประเภทข้อผิดพลาด
progressIndicatorBuilder — พารามิเตอร์ที่ช่วยให้แสดงความคืบหน้าของการดาวน์โหลดเป็นเปอร์เซ็นต์ DownloadProgress ประกอบด้วย totalSize (อาจเป็น -1 หากไม่ทราบ) และ downloadedSize
CachedNetworkImage(
imageUrl: "https://example.com/large.jpg",
progressIndicatorBuilder: (context, url, downloadProgress) {
return Center(
child: SizedBox(
width: 50,
height: 50,
child: Stack(
alignment: Alignment.center,
children: [
CircularProgressIndicator(
value: downloadProgress.progress,
),
Text(
"\(downloadProgress.downloadedSize ~/ 1024) KB",
),
],
),
),
};
},
imageBuilder: (context, imageProvider) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
};
},
)
imageBuilder — พารามิเตอร์เสริมที่ช่วยให้ปรับแต่งการแสดงรูปภาพ: เพิ่มมุมโค้ง เงา ตกแต่ง ตัวอย่างใช้ DecorationImage พร้อม BorderRadius สำหรับมุมโค้ง
CachedNetworkImageProvider — ผู้ให้บริการสำหรับ Image หรือ DecorationImage โดยไม่ต้องใช้วิดเจ็ต CachedNetworkImage มีประโยชน์เมื่อทำงานกับ BoxDecoration, FadeInImage หรือวิดเจ็ต Image ที่กำหนดเอง
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider(
"https://example.com/bg.jpg",
maxWidthBytes: 2048,
maxHeightBytes: 2048,
),
fit: BoxFit.cover,
),
),
)
พารามิเตอร์ imageBuilder ใน CachedNetworkImage ช่วยให้แทนที่วิดเจ็ต Image มาตรฐานด้วยการใช้งานที่กำหนดเอง แทนที่จะแสดง Image โดยตรง คุณสามารถใช้ Container พร้อมการตกแต่ง, ClipRRect สำหรับการครอบตัด หรือ Ink.image สำหรับเอฟเฟกต์ระลอกคลื่น imageBuilder รับบริบทและ ImageProvider ของรูปภาพที่พร้อม ซึ่งให้การควบคุมการเรนเดอร์อย่างสมบูรณ์
พารามิเตอร์เพิ่มเติม: memCacheWidth และ memCacheHeight จำกัดขนาดของรูปภาพที่ถูกแคชใน RAM ลดภาระบน ImageCache ของ Flutter cacheKey ช่วยให้ตั้งคีย์แคชที่กำหนดเองแทน URL ซึ่งมีประโยชน์สำหรับรูปภาพที่มีโทเค็นการอนุญาตใน URL (พารามิเตอร์คำค้นหาเปลี่ยนแปลงในทุกคำขอ แต่เนื้อหายังคงเหมือนเดิม)
วิดเจ็ต Image.network มาตรฐานโหลดรูปภาพทุกครั้งที่สร้างวิดเจ็ตใหม่โดยไม่บันทึกลงดิสก์ CachedNetworkImage เพิ่มการแคชไฟล์ ตัวบ่งชี้ความคืบหน้า และการจัดการข้อผิดพลาด แต่เพิ่มการพึ่งพา flutter_cache_manager และ SQLite
| เกณฑ์ | Image.network | CachedNetworkImage |
|---|---|---|
| แคชบนดิสก์ | ไม่ (เฉพาะแคชหน่วยความจำของ Flutter) | ใช่ (SQLite + ไฟล์) |
| ความคืบหน้า | ไม่ | progressIndicatorBuilder |
| วิดเจ็ตข้อผิดพลาด | เฉพาะตัวยึดตำแหน่งสีแดงใน debug | errorWidget ที่กำหนดเอง |
| TTL แคช | ไม่เกี่ยวข้อง | ปรับแต่งได้ (ค่าเริ่มต้น 7 วัน) |
| การพึ่งพา | ไม่มี (ในตัวของ Flutter) | cached_network_image + flutter_cache_manager + sqflite |
| การเข้าถึงแบบออฟไลน์ | ไม่ | ใช่ (กับไฟล์ที่โหลดไว้ก่อนหน้า) |
| ขนาดบิลด์ | 0 KB เพิ่มเติม | ~300 KB เพิ่มเติม |
สำหรับโปรเจคที่ความสามารถแบบออฟไลน์และการประหยัดแบนด์วิดท์เป็นสิ่งสำคัญ CachedNetworkImage เป็นตัวเลือกที่ชัดเจน สำหรับหน้าจอเดี่ยว ๆ ธรรมดา (เช่น การแนะนำหรือ splash) Image.network ไม่ต้องการการพึ่งพาเพิ่มเติม
CachedNetworkImage ถูกเพิ่มเป็นการพึ่งพามาตรฐานของ pub.dev หลังจากติดตั้ง วิดเจ็ตพร้อมใช้งาน flutter_cache_manager ถูกรวมเป็นการพึ่งพาแบบทรานซิทีฟ
// pubspec.yaml
dependencies:
flutter:
sdk: flutter
cached_network_image: ^3.4.1
โดยค่าเริ่มต้น ใช้ DefaultCacheManager พร้อมการตั้งค่า: TTL = 7 วัน, สูงสุด 200 ไฟล์ ในการเปลี่ยนพารามิเตอร์ทั่วโลก ให้สร้างอินสแตนซ์ CacheManager ที่กำหนดเองด้วย Config โดยที่ maxAgeCacheObject, maxNrOfCacheObjects และ repo ถูกแทนที่
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
final customCacheManager = CacheManager(
Config(
"custom_images",
stalePeriod: Duration(days: 14),
maxNrOfCacheObjects: 500,
repo: JsonCacheInfoRepository(
databaseName: "custom_images_cache.db",
),
),
);
// การใช้ตัวจัดการที่กำหนดเอง:
CachedNetworkImage(
cacheManager: customCacheManager,
imageUrl: url,
// ...
)
maxWidthBytes และ maxHeightBytes — พารามิเตอร์เสริมสำหรับจำกัดขนาดไฟล์ที่ถูกแคช ซึ่งมีประโยชน์ในการประหยัดพื้นที่ดิสก์เมื่อรูปภาพต้นฉบับมีขนาดใหญ่กว่าขนาดหน้าจอที่ต้องการ
คำถามที่พบบ่อย
CachedNetworkImage เป็นวิดเจ็ต Flutter สำหรับโหลดรูปภาพจากเครือข่ายพร้อมแคชอัตโนมัติบนดิสก์ มันจำเป็นสำหรับการประหยัดแบนด์วิดท์ ทำงานในโหมดออฟไลน์ และแสดงความคืบหน้าของการดาวน์โหลด ซึ่ง Image.network มาตรฐานไม่มีให้
เพิ่ม cached_network_image: ^3.4.1 ในส่วน dependencies ของไฟล์ pubspec.yaml และรัน flutter pub get จากนั้นนำเข้าแพ็คเกจในไฟล์ของคุณ: import 'package:cached_network_image/cached_network_image.dart'
สร้าง CacheManager ที่กำหนดเองด้วย Config โดยระบุพารามิเตอร์ stalePeriod เป็น Duration ส่งตัวจัดการที่สร้างไปยังพารามิเตอร์ cacheManager ของวิดเจ็ต CachedNetworkImage โดยค่าเริ่มต้น ไฟล์จะถูกเก็บไว้ 7 วัน
เรียก DefaultCacheManager().emptyCache() เพื่อล้างไฟล์ทั้งหมดอย่างสมบูรณ์ ในการลบเฉพาะไฟล์ที่หมดอายุ ให้ใช้ cleanCache() ตัวจัดการที่กำหนดเองถูกล้างโดยเรียก emptyCache บนอินสแตนซ์ของมัน
ใช่ CachedNetworkImage รองรับ Android, iOS, Web, macOS, Windows และ Linux API ที่เป็นหนึ่งเดียวรับประกันพฤติกรรมที่สอดคล้องกันทุกแพลตฟอร์ม และการแคชทำงานผ่าน flutter_cache_manager ที่ปรับให้เหมาะสมกับแต่ละระบบปฏิบัติการ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ