skip to Main Content

I want to use the errorBuilder callback when an image asset does not exist.
But it’s not called when the Image is used with InkWell + Ink.

main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: Center(
          child: InkWell(
            child: Ink.image(
              image: Image.asset(
                'assets/does-not-exist.png',
                // Not called:
                errorBuilder: (context, error, stackTrace) {
                  return Text('$error');
                },
              ).image,
              fit: BoxFit.cover,
              height: 400,
            ),
            onTap: () {},
          ),
        ),
      ),
    ),
  );
}

2

Answers


  1. Chosen as BEST ANSWER

    I finally made this class in replacement of Ink.image:

    class _InkImage extends StatelessWidget {
      final ImageProvider image;
      final BoxFit? fit;
      final double? width;
      final double? height;
      final errorCompleter = Completer();
    
      _InkImage({
        super.key,
        required this.image,
        this.fit,
        this.width,
        this.height,
      });
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder(
          future: errorCompleter.future,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return SizedBox(
                width: width,
                height: height,
                child: Text('${snapshot.error}'),
              );
            }
            return Ink.image(
              image: image,
              onImageError: (exception, stackTrace) {
                errorCompleter.completeError(exception, stackTrace);
              },
              fit: fit,
              width: width,
              height: height,
            );
          },
        );
      }
    }
    
    

  2. When you are calling Image.asset(...).image, you’re bypassing the Widget, so the error will just disappear. And it’s creating a lot of unnecessary objects. What you should be doing instead is using AssetImage directly (which Image.asset uses under the hood) and setting the Ink.image‘s onErrorBuilder:

    Ink.image(
      image: AssetImage('assets/does-not-exist.png'),
      onImageError: (context, error, stackTrace) {
        return Text('$error');
      },
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search