I'm currently developing an app for deaf people and I need to use many gifs inside my app. I don't want my gifs to play more than once so I used GifImage which lets me control the number of reproductions and the speed of the gif locally.
Now I realize that with so many gifs, my app will be too heavy to upload to the stores, so I tried using CachedNetworkImage to play my gifs from firebase storage. The problem with this library is that I have no control on the reproduction of the gifs, they play infinitely.
What I have already tried:
- Play gif from local file:
GifImage(
controller: controller,
image: AssetImage('test.gif'),
)
- Play gif using CachedNetworkImage:
CachedNetworkImage(
imageUrl:
'https://firebasestorage.googleapis.com/v0/b/app-lsc-7310d.appspot.com/o/test.gif?alt=media',
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width * 0.5,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
I want to know if it is possible to use both libraries together so I can store the gifs in the cache and also have control over them, like so:
CachedNetworkImage(
imageUrl:
'https://firebasestorage.googleapis.com/v0/b/app-lsc-7310d.appspot.com/o/test.gif?alt=media',
imageBuilder: (context, imageProvider) => GifImage(
controller: controller,
image: imageProvider,
),
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
But I get the following error:
[VERBOSE-2:shell.cc(242)] Dart Unhandled Exception: NoSuchMethodError: The getter 'buffer' was called on null.
Receiver: null
Tried calling: buffer, stack trace: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 fetchGif (package:flutter_gifimage/flutter_gifimage.dart:243:76)
#2 GifImageState.didChangeDependencies (package:flutter_gifimage/flutter_gifimage.dart:158:7)
#3 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4653:11)
#4 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4469:5)
#5 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3541:14)
#6 Element.updateChild (package:flutter/src/widgets/framework.dart:3303:20)
#7 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:5981:14)
#8 Element.updateChild (package:flutter/src/widgets/framework.dart:3293:15)
#9 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4520:16)
#10<…>
Here is the full code in case you want to try it out:
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
GifController controller;
String currentGif = 'test';
double frameNum = 25.0;
void initState() {
controller = GifController(vsync: this);
super.initState();
}
playGif(String gifToPlay) async {
controller.value = 0;
controller.animateTo(frameNum - 1,
duration: Duration(milliseconds: (160 * (frameNum - 1)).toInt()));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Giphy'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CachedNetworkImage(
imageUrl:
'https://firebasestorage.googleapis.com/v0/b/app-lsc-7310d.appspot.com/o/test.gif?alt=media',
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width * 0.5,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
SizedBox(
height: 20.0,
),
Card(
child: GifImage(
controller: controller,
image: AssetImage('images/test.gif'),
),
elevation: 7,
),
SizedBox(
height: 20.0,
),
GestureDetector(
onTap: () {
playGif(currentGif);
},
child: Container(
color: Colors.blueGrey,
padding: EdgeInsets.all(5.0),
child: Text(
'Play Local Gif',
style: TextStyle(fontSize: 20),
),
),
),
],
),
),
);
}
}
I am open to other suggestions as well and would be really grateful for your help.