Flutter GIF缓存插件cached_gif的使用

Flutter GIF缓存插件cached_gif的使用

概述

在Flutter中实现GIF动画时,我们可以使用Image组件,但无法对其进行操作,例如更改播放速度、控制播放到某一帧或循环播放特定帧范围。这些问题可以通过此插件解决,并且它还能帮助你缓存GIF以避免每次加载时重新加载每一帧。

示例

以下示例展示了如何异步加载一个GIF并在加载过程中显示文本占位符。当GIF加载完成后,重置控制器并使其播放至结束。

import 'package:flutter/material.dart';
import 'package:cached_gif/cached_gif.dart';

final asset = AssetImage("images/animate.gif");

// 将准备好的GIF添加到缓存中,并在4分钟后从RAM中清除。
unawaited(
  GifCacheManager().addGifToCache(
    asset,
    clearTimeout: const Duration(minutes: 4),
  ),
);

GifController _controller = GifController(vsync: this);

Gif(
  image: asset,
  controller: _controller, // 如果不指定duration和fps,则使用原始GIF的帧率。
  // fps: 30,               
  // duration: const Duration(seconds: 3),
  autostart: Autostart.no,
  placeholder: (context) => const Text('Loading...'),
  onFetchCompleted: () {
    _controller.reset();
    _controller.forward();
  },
)

完整示例代码

import 'package:flutter/material.dart';
import 'package:cached_gif/gif.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  late final GifController controller1, controller2, controller3;
  int _fps = 30;

  [@override](/user/override)
  void initState() {
    controller1 = GifController(vsync: this);
    controller2 = GifController(vsync: this);
    controller3 = GifController(vsync: this);
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          bottom: const TabBar(
            tabs: [
              Tab(
                child: Text('ImageProviders'),
              ),
              Tab(
                child: Text('Manage'),
              )
            ],
          ),
        ),
        body: TabBarView(
          children: [
            ListView(
              clipBehavior: Clip.none,
              children: [
                const Text('AssetImage (original fps, loop)'),
                Gif(
                  autostart: Autostart.loop,
                  placeholder: (context) => const Center(child: CircularProgressIndicator()),
                  image: const AssetImage('assets/rick.gif'),
                ),
                const Text('NetworkImage (30 fps, once)'),
                Gif(
                  fps: 30,
                  autostart: Autostart.once,
                  placeholder: (context) => const Center(child: CircularProgressIndicator()),
                  image: const NetworkImage(
                      'https://i.giphy.com/media/Ju7l5y9osyymQ/giphy.webp'),
                ),
                const Text('NetworkImage (20 seconds, once)'),
                Gif(
                  controller: controller2,
                  duration: const Duration(seconds: 20),
                  autostart: Autostart.once,
                  placeholder: (context) => const Center(child: CircularProgressIndicator()),
                  image: const NetworkImage(
                      'https://i.giphy.com/media/Ju7l5y9osyymQ/giphy.webp'),
                ),
              ],
            ),
            Column(
              children: [
                Gif(
                  controller: controller3,
                  fps: _fps,
                  image: const AssetImage('assets/rick.gif'),
                ),
                AnimatedBuilder(
                  animation: controller3,
                  builder: (BuildContext context, Widget? child) {
                    return Slider(
                      label: 'Timeline',
                      value: controller3.value,
                      onChanged: (v) => setState(() {
                        controller3.value = v;
                      }),
                    );
                  },
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    IconButton(
                      icon: const Icon(Icons.play_arrow),
                      onPressed: () {
                        controller3.repeat();
                      },
                    ),
                    IconButton(
                      icon: const Icon(Icons.stop),
                      onPressed: () {
                        controller3.stop();
                      },
                    ),
                  ],
                ),
                Slider(
                  label: _fps.toString(),
                  value: _fps.toDouble(),
                  min: 1,
                  max: 60,
                  divisions: 4,
                  onChanged: (v) => setState(() {
                    controller3.stop();
                    _fps = v.round();
                  }),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }
}

更多关于Flutter GIF缓存插件cached_gif的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter GIF缓存插件cached_gif的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用cached_gif插件来缓存和显示GIF图像的示例代码。cached_gif是一个用于缓存GIF图像的Flutter插件,可以有效减少重复加载相同GIF的开销。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加cached_gif的依赖:

dependencies:
  flutter:
    sdk: flutter
  cached_network_image: ^3.1.0  # cached_gif依赖于cached_network_image
  cached_gif: ^2.0.0  # 确保使用最新版本

然后运行flutter pub get来安装依赖。

2. 导入插件

在你的Dart文件中导入cached_gif插件:

import 'package:flutter/material.dart';
import 'package:cached_gif/cached_gif.dart';

3. 使用CachedGifImage

下面是一个简单的示例,展示了如何使用CachedGifImage来加载和缓存GIF图像:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cached GIF Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Cached GIF Example'),
        ),
        body: Center(
          child: CachedGifImage(
            imageUrl: 'https://example.com/path/to/your/gif.gif',
            placeholder: CircularProgressIndicator(), // 加载时的占位符
            errorWidget: Icon(Icons.error), // 加载失败时的占位符
          ),
        ),
      ),
    );
  }
}

4. 额外配置(可选)

CachedGifImage还提供了许多可选参数来定制其行为,例如设置缓存大小、缓存位置等。以下是一个更复杂的示例,展示了如何使用这些可选参数:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cached GIF Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Cached GIF Example with Options'),
        ),
        body: Center(
          child: CachedGifImage(
            imageUrl: 'https://example.com/path/to/your/gif.gif',
            placeholder: CircularProgressIndicator(),
            errorWidget: Icon(Icons.error),
            fit: BoxFit.cover, // 图片如何适应容器
            width: 300, // 图片宽度
            height: 300, // 图片高度
            crossFadeDuration: Duration(seconds: 1), // 图片加载完成时的淡入动画时长
            useDiskCache: true, // 是否使用磁盘缓存
            cacheConfig: CacheConfig(
              maxSize: 100 * 1024 * 1024, // 缓存最大大小(100MB)
            ),
          ),
        ),
      ),
    );
  }
}

注意事项

  • 确保GIF图像的URL是有效的,并且服务器支持CORS(跨源资源共享)。
  • cached_gif依赖于cached_network_image,因此它会自动处理网络图像的缓存逻辑。
  • 缓存的配置可以根据你的应用需求进行调整,例如缓存大小、位置等。

通过上述步骤,你应该能够在Flutter项目中成功使用cached_gif插件来缓存和显示GIF图像。

回到顶部