flutter CachedNetworkImage doesn't work as expected - flutter

I'm trying to work with cached images.
I followed this https://flutter.dev/docs/cookbook/images/cached-images,
but it doesn't work.
CachedNetworkImage throws error: "The argument type 'CircularProgressIndicator' can't be assigned to the parameter type '(BuildContext, String) → Widget'. (argument_type_not_assignable at [hello2] lib/main.dart:21)"
Below is the problem code:
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final title = 'Cached Images';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: CachedNetworkImage(
placeholder: CircularProgressIndicator(),
imageUrl:
'https://picsum.photos/250?image=9',
),
),
),
);
}
}
```dart

reinstall your application and then run again will work, it worked for me
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
class App extends StatelessWidget {
const App({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
final title = 'Cached Images';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: CachedNetworkImage(
placeholder: (context, url) => CircularProgressIndicator(),
imageUrl: 'https://picsum.photos/250?image=9',
),
),
),
);
}
}

It works after changing:
placeholder: CircularProgressIndicator(),
to:
placeholder: (context, url) => new CircularProgressIndicator(),
BTW: cached_network_image had a breaking change in 0.6.0.
The tutorial link (https://flutter.dev/docs/cookbook/images/cached-images) is out of date.

I would like to add explanation to the above agreed answer.
placeholder is of type Widget Function(BuildContext, String)? placeholder
So it throws you error:
The argument type CircularProgressIndicator can't be assigned to the parameter type (BuildContext, String) → Widget
Convert:
placeholder: CircularProgressIndicator()
to
placeholder: (context, url) => new CircularProgressIndicator(),

Related

Why Flutter complains about 2 body parameters?

In the tutorial we see two body parameters: https://docs.flutter.dev/get-started/codelab
Like that:
body: const Center(
22
- child: Text('Hello World'),
23
+ body: Center(
24
+ child: Text(wordPair.asPascalCase),
But on the dartpad.dev I have an error:
The argument for the named parameter 'body' was already specified.
I have this code:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(title: Text('Hello there')),
body: const Center(
child: Text('The word is'),
),
body: Center(child: Text(wordPair)),
),
);
}
}
The first snippet shows the changes made in the starter code. They don't coexist
If you look at the left you see the minus and plus sign.

Flutter: How to add a zoom functionality to image

In my flutter app, a custom image is built with the following code
customImage.dart
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
Widget cachedNetworkImage(mediaUrl) {
return CachedNetworkImage(
imageUrl: mediaUrl,
fit: BoxFit.cover,
placeholder: (context, url)=>
Padding(padding: EdgeInsets.all(20.0),
child: CircularProgressIndicator(),
),
errorWidget: (context, url, error) => Icon(Icons.error) ,
);
}
I want to add a functionality to pinch to zoom on this image,how can I achieve that?
You can copy paste run full code below
You can use Flutter's bulid-in InteractiveViewer https://api.flutter.dev/flutter/widgets/InteractiveViewer-class.html
A widget that enables pan and zoom interactions with its child.
working demo
full code
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
Widget cachedNetworkImage(mediaUrl) {
return CachedNetworkImage(
imageUrl: mediaUrl,
fit: BoxFit.cover,
placeholder: (context, url) => Padding(
padding: EdgeInsets.all(20.0),
child: CircularProgressIndicator(),
),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: MyStatelessWidget(),
),
);
}
}
/// This is the stateless widget that the main application instantiates.
class MyStatelessWidget extends StatelessWidget {
MyStatelessWidget({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: InteractiveViewer(
boundaryMargin: EdgeInsets.all(20.0),
minScale: 0.1,
maxScale: 1.6,
child: cachedNetworkImage("https://picsum.photos/250?image=9"),
),
);
}
}
Use photo_view for this. It allows you to create zoomable image widgets without dealing with pinch gesture or sth.
import 'package:photo_view/photo_view.dart';
#override
Widget build(BuildContext context) {
return Container(
child: PhotoView(
imageProvider: AssetImage("assets/image.jpg"),
)
);
}
Source: https://pub.dev/packages/photo_view

Flutter image builder callback issue

I have a problem with using the Image error builder. For example I want to change another widget in the tree to not have a colour. I thought about using a boolean flag but it seems messy. Is there a simple way to do this. Below is an example of what i mean
return Stack(
children: [
Image.file(
File("Some path"),
errorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
// If error builder draws i want the container below colour to become transparent...
// how do i do this?
return Text('Error');
},
),
Container(
height: 100,
width: 200,
color: Colors.red,
),
],
);
You can copy paste run full code below
You can use StreamBuilder and call _events.add(Colors.transparent); in errorBuilder
In working demo, I use image.network to simulate your case, you can directly modify to Image.file
code snippet
Image.file(
File(widget.path),
errorBuilder:
(BuildContext context, Object exception, StackTrace stackTrace) {
_events.add(Colors.transparent);
return Text('Error');
},
),
StreamBuilder<Color>(
stream: _events.stream,
builder: (BuildContext context, AsyncSnapshot<Color> snapshot) {
return Container(
height: 100,
width: 200,
color: snapshot.data,
);
})
working demo
full code
import 'package:flutter/material.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ImageHandelError(
path: 'https://picsum.photos/250?image=9',
),
ImageHandelError(
path: 'not exist',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class ImageHandelError extends StatefulWidget {
String path;
ImageHandelError({this.path});
#override
_ImageHandelErrorState createState() => _ImageHandelErrorState();
}
class _ImageHandelErrorState extends State<ImageHandelError> {
StreamController<Color> _events;
#override
initState() {
super.initState();
_events = StreamController<Color>();
_events.add(Colors.red);
}
#override
Widget build(BuildContext context) {
return Stack(
children: [
Image.network(
widget.path,
errorBuilder:
(BuildContext context, Object exception, StackTrace stackTrace) {
_events.add(Colors.transparent);
return Text('Error');
},
),
StreamBuilder<Color>(
stream: _events.stream,
builder: (BuildContext context, AsyncSnapshot<Color> snapshot) {
return Container(
height: 100,
width: 200,
color: snapshot.data,
);
})
],
);
}
}
I would advice you to use an empty image to fill the gap when ever error happen
child: FadeInImage.assetNetwork(
image: "https://cdn-icons-png.flaticon.com/512/270/270014.png",
fit: BoxFit.fitWidth,
placeholder: Assets.logo_place_holder,//this the image you have prepared
imageErrorBuilder: (_, __, ___) {
return Image.asset(Assets.logo_place_holder); //this is what will fill the Container in case error happened
},
),
or you can Just return a Container and assign color to it and it will spared to fill out the area
this is what it will look like
and this what its look like with Container
this is what it will look like
return Container(color: Colors.red,);

How to Use Blurhash in flutter App or Flutter Project

CachedNetworkImage(
imageUrl: "http://via.placeholder.com/350x150",
placeholder: (context, url) => new CircularProgressIndicator(),
// i want to use Blurhash on placeholder
errorWidget: (context, url, error) => new Icon(Icons.error),
),
https://pub.dev/packages/blurhash
i didn't found Any single Tutorial on it..
I Need Help
You can copy paste run full code below
You can await BlurHash image in main() and then use in CachedNetworkImage
code snippet
Uint8List imageDataBytes;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
imageDataBytes =
await BlurHash.decode("LBAdAqof00WCqZj[PDay0.WB}pof", 32, 32);
runApp(MyApp());
}
...
CachedNetworkImage(
imageUrl: 'https://via.placeholder.com/150x150',
placeholder: (BuildContext context, String url) =>
Image.memory(imageDataBytes, width: 256, fit: BoxFit.cover),
errorWidget: (context, url, error) => new Icon(Icons.error),
),
working demo snapshot
full code
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'dart:typed_data';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:blurhash/blurhash.dart';
Uint8List imageDataBytes;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
imageDataBytes =
await BlurHash.decode("LBAdAqof00WCqZj[PDay0.WB}pof", 32, 32);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CachedNetworkImage(
imageUrl: 'https://via.placeholder.com/150x150',
placeholder: (BuildContext context, String url) =>
Image.memory(imageDataBytes, width: 256, fit: BoxFit.cover),
errorWidget: (context, url, error) => new Icon(Icons.error),
),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

How to zoom image in flutter with CachedNetworkImage widget

can you suggest a way to zoom an image inside a CachedNetworkImage?
Here is my code
CachedNetworkImage(
imageUrl: "http://via.placeholder.com/350x150",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
I tried to wrap CachedNetworkImage in a photo_view widget but it does not work
#override
Widget build(BuildContext context) {
return Container(
child: PhotoView(
imageProvider: CachedNetworkImage(
imageUrl: "http://via.placeholder.com/350x150",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
)
)
);
}
You can copy paste run full code below
Package Cached network image provide CachedNetworkImageProvider
code snippet
PhotoView(
imageProvider:
CachedNetworkImageProvider("http://via.placeholder.com/350x150"),
)
working demo
full code
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(flex: 1, child: PhotoViewTest()),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class PhotoViewTest extends StatefulWidget {
#override
_PhotoViewTestState createState() => _PhotoViewTestState();
}
class _PhotoViewTestState extends State<PhotoViewTest> {
#override
Widget build(BuildContext context) {
return Container(
child: PhotoView(
imageProvider:
CachedNetworkImageProvider("http://via.placeholder.com/350x150"),
),
);
}
}
You can wrap Photo view inside Cached Network image like this code, so you can use advantages of both cached network image and photo view
CachedNetworkImage(
imageUrl: "http://via.placeholder.com/350x150",
imageBuilder: (context, imageProvider) => PhotoView(
imageProvider: imageProvider,
),
placeholder: (context, url) =>
CircularProgressIndicator(),
errorWidget: (context, url, error) =>
Icon(Icons.error),
)
Widget build(BuildContext context) {
return Container(
child: CachedNetworkImage(
imageUrl: "http://via.placeholder.com/350x150",
imageBuilder: (context, imageProvider) => PhotoView(
imageProvider: imageProvider,
)
),
);
}