Rive在Flutter开发中的基本用法

概述

Rive Flutter(以下简称Rive)是Rive提供的运行库,是一个实时交互设计和动画工具,可以帮助Flutter开发者在应用中嵌入复杂的动画。设计人员和开发人员可以使用协作编辑器创建响应不同状态和用户输入的动态图形,然后使用Rive Flutte库的API 将动画加载到他们的项目中。

为Flutter项目添加Rive动画

使用Widget :RiveAnimation.asset() 或者 RiveAnimation.network()

1、使用网络资源

RiveAnimation.network(
  'https://路径.riv',
)

2、使用本地资源

RiveAnimation.asset(
  'assets/Rive文件名.riv',
)

一些名词

artboard --画板

画板可以有无限个,但是不能少于一个画板

State Machines -- 状态机(状态控制器)

State Machines 用于组合一组动画。在设动画计中,可以用可视化的操作面板 将动画连接在一起并设置 状态转换的逻辑,设计者可以控制 并且 管理 它们。一旦State Machines实例化并开始运行,就可以更改该动画提供给开发者用于操控动画的变量( bool值 、double值 、 触发触发器) 来完成状态转换。(可以登入rive官网尝试设计动画以便理解哟!)

若要在开发中使用StateMachines 控制动画可以先在 自定义Utils文件 下创建一个静态的方法用于生成StateMachines,然后在实例化Rive动画时传入到其StateMachines参数内

  /// artboard画板
  /// stateMachineName状态控制器名字
  static StateMachineController getRiveController(Artboard artBoard,
      {stateMachineName = "State Machine 1"}) {
    //返回类型可空,
    //从一个画板中获取状态控制器
    StateMachineController? controller =
        StateMachineController.fromArtboard(artBoard, stateMachineName);
    //为这个画板添加状态控制器
    artBoard.addController(controller!);
    return controller;
  }
 RiveAnimation.asset(
     "Rive文件名.riv",
    artboard: "画板名",
    //初始化时的回调方法   
    onInit: (artboard) {
        //要用该画板的状态控制器
        StateMachineController controller =
            Utils.getRiveController(artboard,
                stateMachineName: "stateMachine名字(问动画设计者)");
        //这个状态控制器 可供使用的input
        input = controller.findSMI("active") as SMIBool;
    },
)

可以在一些特殊事件的回调中更改input的值,以控制动画

                GestureDetector(
                      //假设在点击事件中更改 State Machine
                      onTap: () {
                        //-----------------------------
                        input!.change(true);
                        //-----------------------------
                        //同步index
                        if (selectIcon != bottomNavs[index]) {
                          //要求重新绘制
                          setState(() {
                            selectIcon = bottomNavs[index];
                          });
                        }
                        //页面跳转
                        _controller.animateToPage(index,
                            duration: const Duration(seconds: 1),
                            curve: Curves.easeOutQuad);
                        Future.delayed(const Duration(milliseconds: 500), () {
                          bottomNavs[index].input!.change(false);
                        });
                      },
                //...

选择画板artboard

当一个Rive对象 实例化时,可以指定要使用的artboard。如果没有给出artboard,则使用默认的artboard。一次只能使用一个画板。

RiveAnimation.network(
    //...
    artboard: 'Truck'
);

控制动画 

每个动画和state machines的播放都可以单独控制。你可以使用play(), pause()和stop()方法 播放 或 暂停。

由于Flutter处理方式与其他环境略有不同。Flutter中的每个动画和state machines都被一个 管理动画状态的底层控制器 所管理。当您将动画名称列表传递给RiveAnimation时,它将为每个动画创建并管理 控制器。为了控制动画,你需要为每个动画实例化一个RiveAnimationController,并将控制器传递给RiveAnimation Widget(而不是它的名称)。您可以混合匹配传入控制器和名称,但要避免传入同一动画。

使用控制器以控制动画:

SimpleAnimation控制器 >> 控制暂停/播放

SimpleAnimation是一个基本的控制器,它提供单个动画的简单播放控制。有了这个控制器,你可以播放、暂停和重置动画。

在下面的例子中,SimpleAnimation的isActive属性用于播放和暂停单个动画。

class PlayPauseAnimation extends StatefulWidget {
  //...
}

class _PlayPauseAnimationState extends State<PlayPauseAnimation> {
  /// 控制器
  late RiveAnimationController _controller;

  /// 一个方法 用于 在播放和暂停动画状态之间切换
  void _togglePlay() =>
      setState(() => _controller.isActive = !_controller.isActive);

  /// 通过控制器是否运行来跟踪动画是否正在播放
  bool isPlaying = _controller.isActive;

  @override
  void initState() {
    super.initState();
	//初始化一个SimpleAnimation控制器
    _controller = SimpleAnimation('idle');
  }

  @override
  Widget build(BuildContext context) {
    return //...
			
        (child: RiveAnimation.network(
          //...
		  // 向动画传入一个控制器
          controllers: [_controller],
          // 当Widget初始化时 更新播放状态
		//里面是一个setState()空体,要求系统重新渲染
          onInit: () => setState(() {}),
        ),
      ),
      floatingActionButton: FloatingActionButton(
		//当点击这个按钮时,控制器暂停变播放(或者播放变暂停),并且重新渲染
        onPressed: _togglePlay,
        tooltip: isPlaying ? 'Pause' : 'Play',
        child: Icon(
          isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }
}

OneShotAnimation控制器 >> 控制一次性动画的循环

一次性动画 不会循环OneShotAnimation是一个控制器,当动画已经播放完毕后,它会自动停止并重置一个一次性动画,所以它可以满足重复播放的需要。

OneShotAnimation提供了两个回调函数:onStart()和onStop(),它们将分别在动画开始和停止播放时触发。

//已省略不必要的代码
class PlayOneShotAnimation extends StatefulWidget {
	 //...
}

class _PlayOneShotAnimationState extends State<PlayOneShotAnimation> {
  /// 控制器
  late RiveAnimationController _controller;

  /// 当前动画是否播放
  bool _isPlaying = false;

  @override
  void initState() {
    super.initState();
		//给控制器赋值
    _controller = OneShotAnimation(
      'bounce',
      autoplay: false,
			//停止播放时: _isPlaying = false
      onStop: () => setState(() => _isPlaying = false),
			//开始播放时: _isPlaying = true
      onStart: () => setState(() => _isPlaying = true),
    );
  }

  @override
  Widget build(BuildContext context) {
    return // ....
        child: RiveAnimation.network(
          '...',
          animations: const ['idle', 'curves'],
          controllers: [_controller],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        // 在播放动画时禁用按钮
        onPressed: () => _isPlaying ? null : _controller.isActive = true,
        tooltip: 'Play',
        child: const Icon(Icons.arrow_upward),
      ),
    );
  }
}

布局

Rive提供了许多方法来控制你的 动画 在 画布 或 视图 中的布局。Rive允许您控制渲染内容的适合度、对齐方式和偏移量。

通常在实例化Rive对象时提供布局数据,但开发者也可以随时更新这些值。

参数FitAlignment可以通过RiveAnimation和Rive构造方法 传入。FitAlignment参数用法与其在Flutter中的对应选项类似。

// 填充画布,如有必要裁剪
var widget = const RiveAnimation.network(
  '...',
  fit: BoxFit.cover,
);

//适合宽度并对齐到画布的顶部
widget = const RiveAnimation.network(
  '...',
  fit: BoxFit.fitWidth,
  alignment: Alignment.topCenter,
);

由于笔者水平有限,若你觉得文章有不足之处,希望你在看到之后能够在评论里指出来,看到之后我尽快的回复你。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值