[Flutter]如何使用Rive动画

Rive2动画效果:

ezgif-4-3e0e6218bced.gif

预览网站:rive-nav.liugl.cn/

开始使用

Rive2文件的后缀为.riv,将文件拖到Rive预览工具可以查看文件内提供的动画和状态

image.png

有了动画列表就可以开始准备使用了

添加依赖
rive: ^0.7.17

.riv文件放到指定目录并引用

assets:
    - riv_files/
复制代码

引入依赖
import 'package:rive/rive.dart';

这里我们制作的是一个简单的动画图标,所以只有两个动画:idleactive

针对该图标的属性进行简单的封装:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rive/rive.dart';

///rive图标封装
class RiveIcon extends StatefulWidget {
  const RiveIcon({
    Key? key,
    required this.isSelected,
    required this.rivPath,
    this.idle = 'idle',
    this.active = 'active',
  }) : super(key: key);

  ///是否选中
  final bool isSelected;

  ///文件路径
  final String rivPath;

  ///闲置状态
  final String idle;

  ///激活状态
  final String active;

  @override
  _RiveIconState createState() => _RiveIconState();
}

class _RiveIconState extends State<RiveIcon> {
  ///画布
  Artboard? _riveArtboard;

  @override
  void initState() {
    super.initState();
    _init();
  }

  @override
  void setState(VoidCallback fn) {
    if (mounted) super.setState(fn);
  }

  @override
  void didUpdateWidget(covariant RiveIcon oldWidget) {
    if (oldWidget.isSelected != widget.isSelected) {
      widget.isSelected ? _select() : _unSelect();
    }

    super.didUpdateWidget(oldWidget);
  }

  @override
  void dispose() {
    _riveArtboard?.remove();
    super.dispose();
  }

  ///选中
  void _select() {
    _riveArtboard?.removeController(SimpleAnimation(widget.idle));
    _riveArtboard?.addController(SimpleAnimation(widget.active));
  }

  ///未选中
  void _unSelect() {
    _riveArtboard?.removeController(SimpleAnimation(widget.active));
    _riveArtboard?.addController(SimpleAnimation(widget.idle));
  }

  ///初始化
  Future<void> _init() async {
    _riveArtboard =
        RiveFile.import(await rootBundle.load(widget.rivPath)).mainArtboard;

    setState(() {});

    widget.isSelected ? _select() : _unSelect();
  }

  @override
  Widget build(BuildContext context) {
    return _riveArtboard == null
        ? const SizedBox.shrink()
        : Rive(artboard: _riveArtboard!);
  }
}
复制代码

这样做封装是为了更好地控制动画的状态,非循环的rive动画在被添加时只会播放一次,想重新从头开始播放需要移除该动画并重新添加

///选中
void _select() {
    _riveArtboard?.removeController(SimpleAnimation(widget.idle));
    _riveArtboard?.addController(SimpleAnimation(widget.active));
}

///未选中
void _unSelect() {
    _riveArtboard?.removeController(SimpleAnimation(widget.active));
    _riveArtboard?.addController(SimpleAnimation(widget.idle));
}
复制代码

如何使用?

RiveIcon(
    rivPath: 'riv_files/test.riv',
    isSelected: true,
    idle: 'idle',
    active: 'active',
)
复制代码

rivPath为文件路径
修改isSelected以控制动画状态
idleactive的值可根据图标内的动画名自定义

image.png

为什么不推荐使用官方提供的.asset或者.network构造函数?

官方提供的构造函数不包含状态管理,难以切换动画,只适合循环动画或者一次性动画

PS:

Demo地址
rive文件也在demo里面,感兴趣的朋友可以尝试使用
如果对rive动画的制作也感兴趣可以看一下:[Flutter] Rive2(新版Flare)编辑工具简介

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享