I am trying to load images from network and show them in a GridView
. I am using a StatefulWidget
and loading the images inside the build
method. But according to my understanding its not good to make a network call inside the build
method. How can I download images from the network inside my BLoC
file and later pass the list of downloaded images to the widget? Below is my current implementation.
class MovieList extends StatefulWidget { @override State<StatefulWidget> createState() { return MovieListState(); } } class MovieListState extends State<MovieList> { @override void initState() { super.initState(); bloc.fetchAllMovies(); } @override void dispose() { bloc.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Popular Movies'), ), body: StreamBuilder( stream: bloc.allMovies, builder: (context, AsyncSnapshot<ItemModel> snapshot) { if (snapshot.hasData) { return buildList(snapshot); } else if (snapshot.hasError) { return Text(snapshot.error.toString()); } return Center(child: CircularProgressIndicator()); }, ), ); } Widget buildList(AsyncSnapshot<ItemModel> snapshot) { return GridView.builder( itemCount: snapshot.data.results.length, gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), itemBuilder: (BuildContext context, int index) { return GridTile( child: InkResponse( enableFeedback: true, child: Image.network( 'https://image.tmdb.org/t/p/w185${snapshot.data .results[index].poster_path}', fit: BoxFit.cover, ), onTap: () => openDetailPage(snapshot.data, index), ), ); }); } openDetailPage(ItemModel data, int index) { Navigator.push( context, MaterialPageRoute(builder: (context) { return MovieDetailBlocProvider( child: MovieDetail( title: data.results[index].title, posterUrl: data.results[index].backdrop_path, description: data.results[index].overview, releaseDate: data.results[index].release_date, voteAverage: data.results[index].vote_average.toString(), movieId: data.results[index].id, ), ); }), ); } }
We have a simple yet useful method in Flutter which we can use to load our asset images much faster — precacheImage()! This method good the image into the image cache and then whenever the image is used, it will be loaded much faster. However, Image Cache doesn't allow to hold very large images.
Displaying images is fundamental for most mobile apps. Flutter provides the Image widget to display different types of images. To work with images from a URL, use the Image.network() constructor.
File f = File("https://example.com/xyz.jpg"); The whole point is to get the image from the given URL and save it as a File variable.
You can use loadingBuilder which is inbuilt feature from flutter for Image.Network
Image.network( widget.networkUrl, fit: BoxFit.fill, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { if (loadingProgress == null) return child; return Center( child: CircularProgressIndicator( value: loadingProgress.expectedTotalBytes != null ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes! : null, ), ); }, ),
I would recommend you to use https://pub.dartlang.org/packages/cached_network_image
It's really works good for my cases.
Simple code example from their r
CachedNetworkImage( imageUrl: "http://via.placeholder.com/350x150", placeholder: (context, url) => new CircularProgressIndicator(), errorWidget: (context, url, error) => new Icon(Icons.error), ),
or
Image(image: CachedNetworkImageProvider(url))
You should add to the pubspec file
cached_network_image: <actual version here>
into the dependencies section
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With