Dynamic S3 Bucket URL Caching Flutter - flutter

I would like to cache a Network Image from an S3 bucket URL against an id or key. I tried to use the key: parameter but it didn't work. Please advise how I can achieve this. Heres the Cached Network Image code with the 'key' parameter that doesn't seem to do what I intend.
CachedNetworkImage(
key: Key(uni['university_name'].toString()), // Doesn't seem to do the job
imageUrl: uni['image_url'],
placeholder: (context, url) => CardPlaceHolder(),
errorWidget: (context, url, error) => Padding(
padding: EdgeInsets.all(21),
child: Icon(
Icons.error,
size: 30,
color: Colors.red.withOpacity(0.8),
),
),
imageBuilder: (context, imageProvider) => ...

cached_network_image has been updated to handle keys with the cacheKey value. Check out the code below:
CachedNetworkImage(
cacheKey: "my-key",
imageUrl: _url!,
fit: BoxFit.cover,
progressIndicatorBuilder:
(context, url, downloadProgress) =>
Center(
child: Platform.isAndroid
? CircularProgressIndicator()
: CupertinoActivityIndicator(),
),
)

Currently CachedNetworkImage lack cached image retrival by key
Key you used is Widgets key, not related with CachedNetworkImage behavior
Let see what is in inside of CachedNetworkImage
cached_network_image depends on flutter_cache_manager
And flutter_cache_manager has implementation (issue #179) of retrival by key but it still not released in any version
So CachedNetworkImage will miss this functionality till flutter_cache_manager version has released it new versions
Though we can use this functionality, but we need to implement widget from our side
Temporary solution
depend on flutter_cache_manager
/// this is pubspec dependencies:
flutter_cache_manager:
git:
url: https://github.com/Baseflow/flutter_cache_manager
path: flutter_cache_manager
ref: f109a48c31c4b3ed0a2c1ea2a5749c495e4fa2f4
evolve this naive implementaion to match your use case
FutureBuilder<File>(
future: DefaultCacheManager().getSingleFile(
'url', key: 'file-id'),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Image.file(snapshot.data);
}
// implement here some behavior like CachedNetworkImage does
return CircularProgressIndicator();
},
);
PS I'll update answer when CachedNetworkImage will support

Related

CachedNetworkImage in flutter does not work on local images

This maybe a stupid question given the name but does CachedNetworkImage works on local images?
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
class SigninPage extends StatelessWidget {
const SigninPage({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Welcome"),
),
body:
Center(
child: CachedNetworkImage(
imageUrl: 'assets/images/apple_cartoon.png',
imageBuilder: (context, imageProvider) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider, fit: BoxFit.cover)));
},
placeholder: (context, url) =>
const CircularProgressIndicator(),
errorWidget: (context, url, error) => const Icon(Icons.error),
),
),
);
}
}
This returns the error icon
Using Image.asset instead works fine, so I assume that you cannot use local images with CachedNetworkImage but couldn't find any confirmation online and want to be sure this was the case.
CachedNetworkImage is used to retrieve an image from the internet to store it in a cache and then be able to redisplay it even if you have no connection. While your local image doesn't need a connection to be displayed. That's why you can only give a url in the imageUrl field of the Widget
CachedNetworkImage is a flutter library to show images from the internet and keep them in the cache directory.

Flutter - How to handle loading of images that may not exist

Is there any way to handle image url that not containt an image by using CachedNetworkImage package?
This is my code and when I do images loading, these errors are always popping up
CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (context, url) => Center(
child: CircularProgressIndicator(
color: Theme.of(context).accentColor)),
errorWidget: (context, url, error) => BookErrorImage(),
fit: BoxFit.cover,
),
[]

How to preload images with cached_network_image?

I've just implemented the Flutter package cached_network_image and I wonder how I can preload images so they're available later in an instant. I retrieve all image-urls that will be used later from the our server.
I've defined my custom cache manager getter:
class LocalCacheManager {
static const key = 'customCacheKey';
static CacheManager instance = CacheManager(
Config(
key,
stalePeriod: const Duration(days: 14),
maxNrOfCacheObjects: 200,
repo: JsonCacheInfoRepository(databaseName: key),
fileSystem: LocalCacheFileSystem(key),
fileService: HttpFileService(),
),
);
}
Here's how I currently try to preload the image:
LocalCacheManager.instance.downloadFile(MY_IMAGE_URL)),
And here's how I create the widget:
child: CachedNetworkImage(imageUrl: MY_IMAGE_URL, cacheManager: LocalCacheManager.instance),
But I can clearly see that files are always cached again as soon as I create the CachedNetworkImage.
You can use Flutter Cache Manager like this
DefaultCacheManager().downloadFile(MY_IMAGE_URL).then((_) {});
Later, just use your cached image like this
child: CachedNetworkImage(imageUrl: MY_IMAGE_URL,),
Simplest and workable way is to use precacheImage (flutter build-in function) with CachedNetworkImageProvider:
Image image = Image(
image: CachedNetworkImageProvider(/* url */),
fit: BoxFit.cover,
);
precacheImage(image.image, context);
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: image,
),
);
cached_network_image: ^2.0.0
CachedNetworkImage(
imageUrl: yoururl,
errorWidget: (context, url, error) => Text("error"),
imageBuilder: (context, imageProvider) => CircleAvatar(
radius: 120,
backgroundImage: imageProvider,
),
placeholder: (context, url) => CircularProgressIndicator(
backgroundColor: primary,
),
),

Render an image widget before showing on screen

My app has a list of pages you can swipe between. These pages include network images. The problem is, the network images are fetched and built only when they are visible, meaning the user watches the whole process happen.
I understand this is the intentional functionality of flutter for efficiency, but I am looking for a way to fetch, load and cache a page (that contains network images) before the user navigates to it.
Now
Goal
In your pubspec.yaml file,
Add this as a dependency
meet_network_image:^0.1.2
In your dart file, where you want the image to be, place this line of code
MeetNetworkImage(
imageUrl:
"Your image url.jpg",
loadingBuilder: (context) => Center(
child: CircularProgressIndicator(),
),
errorBuilder: (context, e) => Center(
child: Text('Error appear!'),
),
),
just use cached_network_image package like this:
CachedNetworkImage(
imageUrl: "image path",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),

Flutter not loading images that failed to load the first time

Switch airplane on mode and navigate to a StatefulWidget that includes a NetworkImage. The image fails to load since there is no connectivity. Now switch on airplane mode off. The image doesn't load. Navigating to another view and back again also doesn't help. Minimizing the app doesn't help, but restarting it completely does.
How would you resolve this? How do I make Flutter try to reload the image connectivity is regained?
Add the flutter_image plugin and use NetworkImageWithRetry.
After 2 days of trying all image plugins and answers on stackoverflow. I realized the error goes away when I go back and come back to same screen. So I retried loading images 3 times.
CachedNetworkImage(
key: ValueKey(imageUrl
.split),
placeholder: (context, url) => Padding(
padding: EdgeInsets.all(
MediaQuery.of(context).size.width * 0.2),
child: CircularProgressIndicator()),
errorWidget: (context, url, error) => CachedNetworkImage(
key: ValueKey(imageUrlsplit +
'retry1'),
placeholder: (context, url) =>
Padding(padding: EdgeInsets.all(MediaQuery.of(context).size.width * 0.2), child: CircularProgressIndicator()),
errorWidget: (context, url, error) => CachedNetworkImage(key: ValueKey(imageUrlsplit + 'retry2'), placeholder: (context, url) => Padding(padding: EdgeInsets.all(MediaQuery.of(context).size.width * 0.2), child: CircularProgressIndicator()), errorWidget: (context, url, error) => Text(error.toString()), imageUrl: imageUrlsplit),
imageUrl: imageUrlsplit),
imageUrl: imageUrlsplit)