Now I am using CircleAvatar to show a background image:
CircleAvatar(
radius: 20,
backgroundColor: Colors.transparent,
backgroundImage: foregroundImage.image,
),
but now it always show this error:
======== Exception caught by image resource service ================================================
The following _Exception was thrown resolving an image codec:
Exception: Invalid image data
When the exception was thrown, this was the stack:
#0 _futurize (dart:ui/painting.dart:5275:5)
#1 ImageDescriptor.encoded (dart:ui/painting.dart:5143:12)
#2 instantiateImageCodec (dart:ui/painting.dart:1999:60)
<asynchronous suspension>
Image provider: NetworkImage("https://static.poemhub.top/2021/5/18/laitn.github.io-favicon.ico", scale: 1.0)
Image key: NetworkImage("https://static.poemhub.top/2021/5/18/laitn.github.io-favicon.ico", scale: 1.0)
====================================================================================================
To fix this problem, I tried this way:
final Image defaultImage = Image.asset('images/Icon-App-83.5x83.5#3x.png');
var foregroundImage = counter.value.favIconUrl == "" ? defaultImage : Image.network(
global.staticResourceUrl + "/" + counter.value.localIconUrl,
loadingBuilder: (context,child,loadingProgress)=>(loadingProgress == null) ? child : CircularProgressIndicator(),
errorBuilder: (context, error, stackTrace) => defaultImage,
);
if image fetch failed or other error, set a default image. But still not fix this problem. I figure out maybe the image think this url icon correct, but CircleAvatar render failed. Is it possible to check the image valid before render using CircleAvatar? what should I do to avoid this problem? How to know the image could render successful? I also have tried to set both foreground picture and background picture like this:
CircleAvatar(
radius: 20,
backgroundColor: Colors.transparent,
foregroundImage: foregroundImage.image,
backgroundImage: defaultImage.image,
),
but it looks like this:
both have background and foreground picture.
bool isErrorOccured = false;
CircleAvatar(
radius: 36,
child: isErrorOccured?Image.asset(""):Image.network(""),
onBackgroundImageError: (_, __) {
setState(() {
isErrorOccured = true;
});
},
),
or
SizedBox(
height: height,
width: height,
child: ClipRRect(
child: networkImageUrl == ''
? Image.asset(assetImageUrl, fit: BoxFit.cover)
: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl: networkImageUrl,
placeholder: (context, url) => const Center(
child: CupertinoActivityIndicator(),
),
errorWidget: (context, url, error) => Container(
color: Colors.grey[300],
child: const Icon(
Icons.error,
color: Colors.red,
),
),
),
borderRadius: BorderRadius.circular(height / 2),
))
Related
I am trying to add Hero animation for a Network Image.
The problem is, when I navigate from one screen to another the image loads again on second screen and so I am not able to see the animation.
After loading complete, if I repeat this navigation (from 1st screen to 2nd) this is working fine.
So the question is, How can I achieve this animation when I navigate for first time?
Error-Output:
Click Here
Code:
FirstScreen.dart
Hero(
tag: 'tag',
child: Image.network(
'https://...',
cacheHeight: 1080,
cacheWidth: 1080,
fit: BoxFit.none,
scale: 5,
),
),
secondScreen.dart
Hero(
tag: 'tag',
child: Image.network(
'https://...',
),
)
With CachedNetworkImage:
firstScreen.dart
Hero(
tag: tag
child: CachedNetworkImage(
imageUrl: 'url',
fit: BoxFit.scaleDown,
height: 200,
width: 200,
memCacheHeight: 1080,
memCacheWidth: 1080,
errorWidget: (context, url, error) => Image.asset('assets/..'),
),
)
secondScreen.dart
Hero(
tag: tag,
child: CachedNetworkImage(
imageUrl: 'url',
errorWidget: (context, url, error) => Image.asset('assets/...'),
),
),
create loading builder in the network image widget and use a placeholder instead of image when the image is not fully loaded something like this
Image.network(
imagePath,
// width: 100,
// height: 100,
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
return Container(
width: 100,
height: 100,
child: Center(
child: // PlaceHolderWidget()
),
);
},
// fit: BoxFit.none,
)
I am trying to use NetworkImage as the image in a BoxDecoration for a Container. The url passed to the NetworkImage will sometimes hold a bad image type (the url works and is correct but the actual image at the specified url is bad) resulting in an error.
To handle this occurrence I set up a method that uses a try-catch block where it returns the NetworkImage if successful, and a preset AssetImage in the event of an error. The try-catch block is not handling this exception, and throws an error instead of returning the AssetImage specified in the catch.
I've seen that Image.network has an onError parameter which looks like it would solve the problem, but Image.network is of type "Image" and BoxDecoration requires an "ImageProvider" (NetworkImage, AssetImage), so that does not help in this case.
Which is the best way to handle this error so that I can show an AssetImage in the case of the NetworkImage throwing an error?
Here is the Widget holding the BoxDecoration where I call the method I created to handle fetching the NetworkImage:
class CharacterPreviewCard extends StatelessWidget {
final CharacterPreview character;
const CharacterPreviewCard({Key? key, required this.character})
: super(key: key);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
context.router
.push(CharacterDetailsRoute(characterId: character.characterId));
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 171,
width: 171,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.black,
image: DecorationImage(
image: getCharacterAvatar(character.characterAvatarUrl),
fit: BoxFit.fill,
),
),
),
const SizedBox(height: smallMargin),
Padding(
padding: const EdgeInsets.only(left: smallMargin),
child: SizedBox(
width: 165,
child: Text(
character.characterName,
style: Theme.of(context).textTheme.bodyLarge,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
),
],
),
);
}
Here is the method "getCharacterAvatar" which should return either NetworkImage or AssetImage:
ImageProvider<Object> getCharacterAvatar(String url) {
try {
final image = NetworkImage(url);
return image;
} catch (e) {
return const AssetImage('assets/images/village-not-found-logo.png');
}
}
And here is the error in Debug Console:
The following _Exception was thrown resolving an image codec:
Exception: Invalid image data
When the exception was thrown, this was the stack
#0 _futurize (dart:ui/painting.dart:5718:5)
#1 ImageDescriptor.encoded (dart:ui/painting.dart:5574:12)
#2 instantiateImageCodec (dart:ui/painting.dart:2056:60)
<asynchronous suspension>
Image provider: NetworkImage("https://narutoql.s3.amazonaws.com/Hana.jpg", scale: 1.0)
Image key: NetworkImage("https://narutoql.s3.amazonaws.com/Hana.jpg", scale: 1.0)
Currently, there is no way to catch errors with NetworkImage or Image.network. More on this can be found here: https://github.com/flutter/flutter/issues/20910.
Thanks to Tom3652's comment suggesting the use of CachedNetworkImage I was able to find a solution that works using the Widget CachedNetworkImage with an errorWidget parameter to display an AssetImage when an error was thrown.
I replaced the Container that had the NetworkImage as a parameter for DecorationImage with a custom widget (to minimized code in the file). The custom widget returns the CachedNetworkImage.
Here is the solution that worked for me:
class PreviewCardImage extends StatelessWidget {
final String url;
final AssetImage errorImage;
const PreviewCardImage({
Key? key,
required this.url,
required this.errorImage,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return CachedNetworkImage(
imageUrl: url,
imageBuilder: (context, imageProvider) => Container(
height: 171,
width: 171,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.black,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fill,
),
),
),
placeholder: (context, url) => const CircularProgressIndicator(),
errorWidget: (context, url, error) => Container(
height: 171,
width: 171,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.black,
image: DecorationImage(
image: errorImage,
fit: BoxFit.fill,
),
),
),
);
}
}
I think you should use the Image.network class replacing your NetworkImage.
It contains especially an errorBuilder parameter that allows you to set a custom widget in case of error :
Image.network(
String src,
{Key? key,
double scale = 1.0,
ImageFrameBuilder? frameBuilder,
ImageLoadingBuilder? loadingBuilder,
ImageErrorWidgetBuilder? errorBuilder,
...
int? cacheWidth,
int? cacheHeight}
)
If you need the ImageProvider, then your method can look like this :
ImageProvider<Object> getCharacterAvatar(String url) {
final image = Image.network(url, errorBuilder: (context, object, trace) {
return Image(image: AssetImage('assets/images/village-not-found-logo.png'));
},).image;
return image;
}
Please note the .image at the end of the Image.network().image to return the ImageProvider.
The following is my code for getting image from camera or gallery and updating the user image if any from server and showing default asset image if there is no user image exist. Can anyone say how can I add loading or shimmer effect when the image from the server is loading?
child: CircleAvatar(
backgroundImage: (_image != null)
? FileImage(_image)
: (_userImage != null && _userImage != "")
? NetworkImage(_userImage)
: AssetImage(
DrawableResource.imagePlaceHolder),
radius: 75,
backgroundColor: Colors.grey,
),
You can try below code or you can use cachedNetworkImage with errorWidget Property from package : cached_network_image: ^3.2.1
package for below code : shimmer: ^2.0.0
child: CircleAvatar(
backgroundImage: (_image != null)
? FileImage(_image)
: (_userImage != null && _userImage != "")
? CachedNetworkImage(
imageUrl: _userImage,
fit: BoxFit.cover,
errorWidget: (context, value, value1) {
return Container(
child: Center(
child:
Text("No image found"),
),
);
},
),
: AssetImage(
DrawableResource.imagePlaceHolder),
radius: 75,
backgroundColor: Colors.grey,
),
Why I cannot use NetworkImage in flutter? I got the error. Which one was I missed?
in my code
Stack(
children: [
_image != null
? CircleAvatar(
radius: 64,
backgroundImage: MemoryImage(_image!),
)
: const CircleAvatar(
radius: 64,
backgroundImage: NetworkImage(user.userimage),
),
Positioned(
bottom: -10,
left: 80,
child: IconButton(
onPressed: selectImage,
icon: const Icon(Icons.add_a_photo),
))
],
),
But I got this error code
and this
A value of type 'Null' can't be assigned to a parameter of type 'String' in a const constructor. Try using a subtype, or removing the keyword 'const'.
the image from FirebaseStorage
firstly you must check the image url is correct or not
and can use "Image.network" that already Inheritance from "NetworkImage"
and i changed your code to be like below , please try it :
const CircleAvatar(
radius: 64,
child: Image.network(
user.userimage,
fit: BoxFit.fill,
errorBuilder:
(context, error, stackTrace) {
return Image.asset(
'put and image here');
},
)
),
Exception caught by image resource service
(
height: 300,
width: double.maxFinite,
child: TabBarView(controller: _tabController, children: [
ListView.builder(
itemCount: 3,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 200,
height: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white,
image: DecorationImage(
image: AssetImage(
"images/levender.jpg",
),
fit: BoxFit.cover,
),
),
);
When the exception was thrown, this was the stack
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49 throw
packages/flutter/src/services/asset_bundle.dart 224:55 load
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1362:47 _rootRunUnary
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1265:19 runUnary
...
Image provider: AssetImage(bundle: null, name: "images/levender.jpg")
Image key: AssetBundleImageKey(bundle: PlatformAssetBundle#0645c(), name: "images/levender.jpg", scale: 1)
It will happen sometimes. sometimes when you add an asset if this error happened just close your emulator and run it again and it will be ok.