Line data Source code
1 : import 'dart:async';
2 :
3 : import 'package:flutter/material.dart';
4 :
5 : /// A widget that precaches the NetworkImage part of a CircleAvatar, checks for
6 : /// any errors and if found, returns a widget that indicates something went
7 : /// wrong.
8 : class CheckedCircleAvatar extends StatelessWidget {
9 : final String _url;
10 : final double _radius;
11 0 : const CheckedCircleAvatar(
12 : {required String url, required double radius, Key? key})
13 : : _url = url,
14 : _radius = radius,
15 0 : super(key: key);
16 0 : Future<bool> cacheImage(String url, BuildContext context) async {
17 : var hasNoError = true;
18 0 : var output = Completer<bool>();
19 0 : await precacheImage(
20 0 : NetworkImage(_url),
21 : context,
22 0 : onError: (e, stackTrace) => hasNoError = false,
23 : );
24 0 : output.complete(hasNoError);
25 0 : return output.future;
26 : }
27 :
28 0 : @override
29 : Widget build(context) {
30 0 : return FutureBuilder(
31 0 : future: cacheImage(_url, context),
32 0 : builder: (context, snapshot) {
33 0 : if (snapshot.connectionState == ConnectionState.none ||
34 0 : snapshot.hasError) {
35 : return const ErrorAvatar();
36 : }
37 0 : if (snapshot.connectionState == ConnectionState.waiting) {
38 0 : return Container(
39 : decoration: const BoxDecoration(color: Colors.grey),
40 : child: const Center(
41 : child: CircularProgressIndicator(),
42 : ),
43 : );
44 : }
45 0 : if (snapshot.data == false) {
46 : return const ErrorAvatar();
47 : }
48 0 : return CircleAvatar(
49 0 : radius: _radius, backgroundImage: Image.network(_url).image);
50 : },
51 : );
52 : }
53 : }
54 :
55 : class ErrorAvatar extends StatelessWidget {
56 25 : const ErrorAvatar({Key? key}) : super(key: key);
57 :
58 0 : @override
59 : Widget build(BuildContext context) {
60 0 : return Container(
61 : height: 80.0,
62 : decoration: const BoxDecoration(color: Colors.grey),
63 : child: const Center(
64 : child: Text(
65 : 'Error',
66 : ),
67 : ),
68 : );
69 : }
70 : }
|