onError method of DecorationImage() in Flutter - flutter

Code works fine but because of my unreliable internet connection I am faced with an issue of NetworkImage.load ( See error image below )
Container(
width: 60,
height: 80,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.all(Radius.circular(7.0))
image: DecorationImage(
image: NetworkImage(trend['imageUrl']),
onError: <how we can handle this?>,
fit: BoxFit.cover
),
),
);
I hope this issue can be fixed by handling it on onError method (Correct me if I'm wrong). But I can't figure it out how to do that.
Error:

First of all lets say you intialize NetworkImage inside your class. like:
var imgVariable = NetworkImage(trend['imageUrl']);
Then, load your network image. If, error occurs then we will load from our assets to let user know that we could not load network image.
Container(
width: 60,
height: 80,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.all(Radius.circular(7.0))
image: DecorationImage(
image: imgVariable,
onError: (errDetails){
setState(){
imgVariable = AssetImage('assets/could_not_load_img.jpg');
};
},
fit: BoxFit.cover
),
),
);
Here, assets/could_not_load_img.jpg is image that is imformative sthg.
*Note: This may not seem to work with errors, but this can be a way I came up with. There are plugins like cached_network_image to work beautifully on network images.

The accepted solution by Biplove doesn't seem to work anymore, at least I couldn't solve the resulting cast error when replacing the NetworkImage with an AssetImage. But a similar way would be:
class _YourClassState extends State<YourClass> {
bool networkError = false;
NetworkImage backgroundImage = const NetworkImage(
'youUrl');
AssetImage backgroundImageFallback = AssetImage('assets/img/....jpg');
...
decoration: !networkError ? DecorationImage(
fit: BoxFit.fill,
onError: (Object e, StackTrace? stackTrace) {
log("Could not load the network image, showing fallback instead. Error: ${e.toString()}");
if (stackTrace != null) {
log(stackTrace.toString());
}
setState(() {
networkError = true;
});
},
image: backgroundImage) :
DecorationImage(
fit: BoxFit.fill,
image: backgroundImageFallback)
}

so, onError in flutter basically takes a return type of function
it takes some error that may generate during the loading/fetching of the response image URL as the parameter Error that is generated during call and a report that provides information about program subroutines that can be found in the debug console as well
onError:(error, stackTrace) => AssetImage('assets/could_not_load_img.jpg'),
or you can check these
[click]https://github.com/flutter/flutter/issues/78925#issuecomment-806553363
[click]https://github.com/flutter/flutter/issues/78925

Related

Dislaying Image File in Container Exported From Video

Trying to export a frame from my video file, save it to an image file list, and then display it back when building my list of containers.
setState(() async{
if (result!.files.isNotEmpty) {
for (PlatformFile item in result.files) {
videos.add(File(item.path!));
var duration = Duration(seconds: 1);
File image = await ExportVideoFrame.exportImageBySeconds(File(item.path!), duration, 0);
videoThumbs.add(image);
//tickets[widget.indexEvent].videos[i]
}
} else {}
});
Then later in my page class I am trying to display it back for the user in a child of my container:
Container(
width: 220,
height: 220,
color: colorPrimary,
child: Image.file(
videoThumbs[i],
width: 100,
height: 100,
fit: BoxFit.fill,
),
),
The code doesn't hard fail, and will build the apk, but when in the app, my thumbnail just says:
As you can see from my thumbnail, my list of photos and videos are building, but when it tries to loop through the videos and show a thumb, the array index is empty, I think? I believe I'm reading that error right.
I have seriously been at this for 2 weeks, and I could really use some help.
in this list, Your data is not complete, on 2 last of your data is null.
use this:
child:
videoThumbs[I] == null? const SizedBox():
Image.file(
videoThumbs[i],
width: 100,
height: 100,
fit: BoxFit.fill,
),

Image cannot be null using FadeInImage and url [Flutter]

Hello so I added a way to display my url images in a list but because Im fetching this information from public API some of them are missing URLs and errors occur, I tried using placeholder and image errorbuilder but that didnt help
Here is my code:
child: FadeInImage.assetNetwork(
height: 100,
width: 100,
fit: BoxFit.fill,
image: newsList[index].urlToImage,
placeholder: 'images/placeholder.png',
imageErrorBuilder: (context, error, StackTrace) {
return const Image(
height: 100,
width: 100,
image: AssetImage("images/placeholder.png"));
},
),
and Error:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building:
'package:flutter/src/widgets/fade_in_image.dart': Failed assertion: line 234 pos 15: 'image !=
null': is not true.
Updated Code:
child: newsList[index].urlToImage == null
? Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/placeholder.png"),
),
),
)
: FadeInImage.assetNetwork(
height: 100,
width: 100,
fit: BoxFit.fill,
image: newsList[index].urlToImage,
placeholder: 'images/placeholder.png',
imageErrorBuilder:
(context, error, StackTrace) {
return const Image(
height: 100,
width: 100,
image:
AssetImage("images/placeholder.png"));
},
),
and error message:
imageErrorBuilder will only be called if there is an error occurs during image loading, example the image path does not exist.
To fix your issue, you have to check whether url is null or empty. If it is null, display another widget, else display FadeInImage.
newsList[index].urlToImage == null ? DisplayNoImage: FadeInImage.assetNetwork(...),

Display image in dialog - the return type 'Future<Uint8List> isn't a Widget

I'm going round in circles with this and would appreciate a fresh viewpoint.
I have the following button, which when tapped must display an image. The image data is fetched from the backend (this part works fine).
IconButton(
icon: Icon(
Icons.attach_email_rounded,
size: 32.0,
),
color: Colors.grey,
onPressed: () async {
await showDialog(
context: context,
builder: (_) => showAttachment( // <-- error here
appstate['arg1'],
appstate['arg2'],
appstate['arg3]),
);
},
)
Function:
Future<Dialog> showAttachment(arg1, arg2, arg3) async {
Uint8List attachmentData;
await getAttachment(arg1, arg2, arg3).then(
(value) => {
attachmentData = value,
},
);
return Dialog(
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: Image.memory(attachmentData).image,
fit: BoxFit.cover,
),
),
),
);
}
However, I'm getting the error The return type 'Future<Dialog>' isn't a 'Widget', as required by the closure's context.
Googling around has revealed I need to use FutureBuilder, but I'm not sure how to incorporate that in the above closure code.
I'd appreciate pointers.
Thanks
The builder functions for showDialog is synchronous, so in order to use a future we'll have to nest a FutureBuilder into the Dialog and keep the containing function synchronous.
I've adapted your code sample to demonstrate:
Dialog showAttachment(arg1, arg2, arg3) {
return Dialog(
child: FutureBuilder<Uint8List>(
future: getAttachment(arg1, arg2, arg3),
builder: (context, snapshot) {
return snapshot.hasData
? Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: Image.memory(snapshot.data!).image,
fit: BoxFit.cover,
),
),
)
: const CircularProgressIndicator();
},
),
);
}
It's important to remember that, unless you provide the optional initial data argument for the FutureBuilder, the first time the builder is called, the snapshot won't have data: so we should check that.
Also not shown above is handling errors; which is done in the same way as checking if the snapshot has data.
FutureBuilder Documentation

type 'FutureBuilder<File>' is not a subtype of type 'ImageProvider<dynamic>' - Image Picker problem

I need to add an image in a Container. The image is coming from IMAGE PICKER.
Im getting the error:
type 'FutureBuilder<File>' is not a subtype of type 'ImageProvider<dynamic>'
Here's the original code:
Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image:
_imageFileForHeader.path != null?
FutureBuilder(
future: _getLocalFile(_imageFileForHeader.path),
builder: (BuildContext context, AsyncSnapshot<io.File> snapshot)
{
return Image.file(snapshot.data);
}
):
NetworkImage(urlImage + _kHeaderImage), fit: BoxFit.cover,
),
),
I really could do with any help here.
If the user does not select an image from the gallery - then use the image in the URL (urlImage).
I think I'm doing a very standard routine, and I cannot see why its not working.
Thanks
-- I just want to add that I tried also :
return FileImage(snapshot.data)
and this did not work either.
I think I exhausted every permutation possible here.
By the way, here's the _getLocalFile...
Future<io.File> _getLocalFile(String filename) async
{
io.File f = new io.File(filename);
return f;
}
You don't need any future in _getLocalFile as there is no async operations inside. You can just do
return Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image: _imageFileForHeader?.path != null
? Image.file(File(_imageFileForHeader.path))
: Image.network(urlImage + _kHeaderImage);
),
),
Or Assuming _imageFileForHeader is already a file we could simplify this even more
return Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image: _imageFileForHeader != null
? Image.file(_imageFileForHeader)
: Image.network(urlImage + _kHeaderImage);
),
),
I think your _getLocalFile function returns the wrong datatype. Maybe if you try the following:
Future<File> _getLocalFile() async{
final ImagePicker _picker = ImagePicker();
PickedFile pickedFile= await _picker.getImage(source: ImageSource.gallery);
File file = File(pickedFile.path);
return file;
}
Futhermore, I don´t belive that you can use a FutureBuilder for the Containers image variable. To display a image inside a Container you can use:
File file;
Container(
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.cover,
image: new FileImage(file),
),
),
),
So I think you have to check the file variable for null and if it is null, maybe show a button. If the user presses the button, you can call the async _getLocalFile function and than maybe update with setState to show the image.
Maybe you could also wrap the image around a FutureBuilder:
FutureBuilder<File>(
future: _getLocalFile(),
builder: (BuildContext context, AsyncSnapshot<File> snapshot)
{
if(!snapshot.hasData){
return CircularProgressIndicator();
}else{
return Container(
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.cover,
image: new FileImage(snapshot.data),
),
),
);
}
}
);

SvgPicture can't be assigned to ImageProvider

I'm trying to use svg image as background in Container and I use this package "flutter_svg" I can't found a Provider method to set it in decoration
Container(
margin: EdgeInsets.symmetric(horizontal: 5),
width: 60,
height: 20,
decoration: BoxDecoration(
color: currentColor.medium,
borderRadius: BorderRadius.circular(4),
image: DecorationImage(
image: SvgPicture.asset('assets/images/home.png'),
),
),
);
The argument type 'SvgPicture' can't be assigned to the parameter type 'ImageProvider'.dart(argument_type_not_assignable)
so I don't know how to use svg as ImageProvider here , any idea
There are two options:
First one, write a function for that, as commented in flutter_svg package at here:
final String rawSvg = '''<svg viewBox="...">...</svg>''';
final DrawableRoot svgRoot = await svg.fromSvgString(rawSvg, rawSvg);
final Picture picture = svgRoot.toPicture();
final Image image = await picture.toImage(width, height);
return RawImage(image, 1.0);
And second one, use another package on top of svg_flutter package:
import 'package:flutter_svg_provider/flutter_svg_provider.dart';
Image(
width: 32,
height: 32,
image: Svg('assets/my_icon.svg'),
)
You should add to your pubspec.yaml, flutter_svg_provider: ^1.0.0 instead of flutter_svg: ^1.0.0
Flutter developers have created one library you can find here
https://www.developerlibs.com/2019/06/flutter-draw-svg-vector-drawables.html