如何在Flutter中显示动画图片?

Rém*_*let 10 dart flutter

我希望在Flutter中显示一个动画图片,无论其格式如何.事实是,目前似乎只有一种解决方案,video_loader.这仅适用于全屏,但不适合我的用例.

关于如何解决这个问题的任何想法?

Upa*_*Jah 31

现在,Image小部件支持GIF.(4月18日)

对于Ex.

new Image(image: new AssetImage("assets/ajax-loader.gif"))

  • @UpaJah 有什么方法可以只播放这个 GIF 一次吗? (2认同)

Col*_*son 18

您可以使用https://ezgif.com/split将帧拆分为单独的图像,并将它们作为资源添加到pubspec.yaml中.

然后使用an Animation<int>选择要显示的正确帧.确保设置gaplessPlayback: true为避免闪烁.

例如,以下代码显示由Guillaume Kurkdjian创建的动画GIF的帧.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData.dark(),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  State createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<int> _animation;

  @override
  void initState() {
    _controller = new AnimationController(vsync: this, duration: const Duration(seconds: 5))
      ..repeat();
    _animation = new IntTween(begin: 0, end: 116).animate(_controller);
  }

  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          new AnimatedBuilder(
            animation: _animation,
            builder: (BuildContext context, Widget child) {
              String frame = _animation.value.toString().padLeft(3, '0');
              return new Image.asset(
                'assets/frame_${frame}_delay-0.04s.png',
                gaplessPlayback: true,
              );
            },
          ),
          new Text('Image: Guillaume Kurkdjian', style: new TextStyle(fontStyle: FontStyle.italic)),
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是我在Stack Overflow上最喜欢的答案之一 (4认同)
  • 如何运行一次而不是循环动画? (4认同)

Shu*_*oni 6

2021 年更新

截至目前,flutter 确实支持gif使用小部件播放文件Image

Image.asset('assets/logo.gif')
Run Code Online (Sandbox Code Playgroud)

gif但是目前flutter的加载方式存在一个问题。循环播放,播放一次后就gif无法停止。gif还有其他使用 Rive 和Lottie来显示动画图片的方法,它们都附带了维护良好的 flutter 包,提供了许多开箱即用的功能。

解决方法:

  1. 将您的 gif 转换为 mp4 ( Gif 转 mp4 )
  2. 将 mp4 转换为 Lottie json ( Mp4 为 Json )
  3. 将 Lottie json 上传到lottiefiles.com或添加到您的assets文件夹
  4. 使用Lottie 包加载你的动画

Lottie 包文档中的示例:

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ListView(
          children: [
            // Load a Lottie file from your assets
            Lottie.asset('assets/LottieLogo1.json'),

            // Load a Lottie file from a remote url
            Lottie.network(
                'https://raw.githubusercontent.com/xvrh/lottie-flutter/master/example/assets/Mobilo/A.json'),

            // Load an animation and its images from a zip file
            Lottie.asset('assets/lottiefiles/angel.zip'),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,这不是加载 gif 的最理想方式,因为这只是一种解决方法。Image如果您不使用gif. 但如果您使用 Lottie,那么您可以通过更多的控制对 gif 进行很多操作。