Why does errorBuilder
of Image.network
not get invoked when in DecorationImage
?
Instead error that occurs in Image.network
invokes onError
of DecorationImage
. So I cannot substitute failed image with another widget.
Here is the code with this situation. I took the example from the documentation for errorBuilder and amended it so that Image.network
is in DecorationImage
. See below:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: Scaffold(
body: Center(
child: MyStatelessWidget(),
),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(),
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
one rror: (obj, st) {
print('ONERROR-ONERROR-ONERROR');
},
image: Image.network(
'https://example.does.not.exist/image.jpg',
errorBuilder:
(BuildContext context, Object exception, StackTrace? stackTrace) {
// Appropriate logging or analytics, e.g.
// myAnalytics.recordError(
// 'An error occurred loading "https://example.does.not.exist/image.jpg"',
// exception,
// stackTrace,
// );
return const Text('ERROR');
},
).image
)
),
child: const SizedBox(height: 200, width: 200),
);
}
}
CodePudding user response:
You are using image:Image.network().image
that returns ImageProvider
. It means image
will get from Image.network
only when there is no error and image load perfectly.
When the issue happens, you can see onError
message.
Now for the use case errorBuilder
return a widget that can't be directly assign on image
.
This might be call overengineered to handle the error.
@override
Widget build(BuildContext context) {
final dImage = DecorationImage(
one rror: (obj, st) {
print('ONERROR-ONERROR-ONERROR');
},
image: Image.network(
'h .exist/image.jpg',
errorBuilder:
(BuildContext context, Object exception, StackTrace? stackTrace) {
debugPrint("onError B");
return Text("rr");
},
).image,
);
return Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(),
borderRadius: BorderRadius.circular(20),
image: dImage.onError != null
? DecorationImage(
image: NetworkImage(imgUrl), //default image URL on null case
)
: dImage,
),
child: const SizedBox(height: 200, width: 200),
);
}
I will prefer using Container child with stack if I need overlay.
We already have child
option and simplify the case. This is a simple and cleaner approach you can just tell by reading the code, don't have to scroll the mouse.
return Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(),
borderRadius: BorderRadius.circular(20),
),
child: Image.network(
'h .exist/image.jpg',
errorBuilder:
(BuildContext context, Object exception, StackTrace? stackTrace) {
debugPrint("onError B");
return Center(child: Text("Error"));
},
),
);