Flutter动画新纪元:Rive助力打造炫酷交互‌

导读:Flutter 生态中,动画一直是提升用户体验的重要利器。而 Rive(https://rive.app/)作为一款实时交互动画设计工具,凭借轻量、高性能和可编程特性,正在为 Flutter 带来“动画新纪元”。本文从“什么是 Rive”讲起,到“如何将 Rive 与 Flutter 结合”,再到“实战案例代码”,“图解”关键流程与原理,帮助你快速上手,打造出炫酷又高效的交互动画。

目录

  1. 什么是 Rive?为什么用 Rive 而非传统 Lottie 或手写动画?
  2. Rive 基础概念与术语解析

    • 2.1 Artboard(画板)
    • 2.2 Shapes 和 Layers(图形与层次)
    • 2.3 Keyframes 与 Timelines(关键帧与时间线)
    • 2.4 State Machine(状态机)
  3. 快速开始:在 Flutter 中集成 Rive

    • 3.1 准备 Rive 文件 .riv
    • 3.2 添加依赖与配置
    • 3.3 加载并显示静态动画
  4. 实战示例一:播放简单动画

    • 4.1 在 Rive 编辑器中创建一个 “Loading” 动画
    • 4.2 Flutter 中显示动画的最简代码
    • 4.3 图解:渲染流程与帧率优化
  5. 实战示例二:State Machine 驱动交互

    • 5.1 在 Rive 中制作带有状态机的按钮动画
    • 5.2 Flutter 中读取 State Machine 并触发状态转换
    • 5.3 代码详解与图解流程
  6. 高级技巧:动态修改属性 & 双向绑定

    • 6.1 通过 Flutter 代码实时修改 Rive 的属性(颜色、形状、数值)
    • 6.2 双向绑定:监听 Rive 内部回调,触发 Flutter 逻辑
    • 6.3 图解:属性流与事件流
  7. 性能优化与最佳实践

    • 7.1 限制渲染区域与使用 RiveAnimationController
    • 7.2 减少不必要的 Artboard reload
    • 7.3 AOT 下动态加载与预缓存
  8. 总结与扩展思考

一、什么是 Rive?为什么用 Rive 而非传统 Lottie 或手写动画?

  • Rive 是一款集“设计—交互—实时渲染”于一体的矢量动画创作工具。设计师在 Rive 编辑器中绘制图形、配置动画、编写状态机;开发者通过 Rive Flutter Runtime 将其无缝嵌入应用,高性能地渲染效果。
  • 与 Lottie 对比

    • Lottie(Bodymovin)主要依赖 After Effects 导出 JSON,逐帧播放,适用于简单动画,但对交互、双向绑定支持有限。
    • Rive 支持 “实时” 动态控制:不仅可以播放预制动画,还能通过状态机在运行时根据业务逻辑触发不同动画,还可在 Flutter 侧实时修改 Rive 实例中的属性(如渐变颜色、大小、形状参数等)。
  • 手写 Flutter 动画 vs Rive

    • Flutter 自带 AnimationControllerTweenCustomPainter 等强大工具,但若动画效果需求复杂(例如交互性、可编辑的动态形变、循环节奏精准把控),需要耗费大量时间去调试。
    • Rive 编辑器提供可视化、实时预览的创作环境,设计师与开发者协同无缝:设计师调好状态机、帧率、Bezier 曲线、缓动函数等后导出 .riv,开发者只需加载并调用状态机接口。

二、Rive 基础概念与术语解析

在踏入 Flutter 代码前,我们先梳理核心概念,帮助理解接下来所用到的文件结构与运行时逻辑。

2.1 Artboard(画板)

  • Artboard 类似于 After Effects 的“合成”,是一个容纳所有图形与动画的容器。一个 .riv 文件中可以包含多个 Artboard,每个自由定义不同动画或 UI 组件。
  • 在 Rive 编辑器中,Artboard 主界面的左上角即显示当前所选 Artboard 的名称。导出时,Flutter 端可通过名字获取对应的 Artboard 实例。

    +─────────────────────────────────+
    │     Artboard: LoadingScreen    │  ← 画板名称
    │ ┌─────────────────────────────┐ │
    │ │   [Vector shapes, layers…]   │ │
    │ └─────────────────────────────┘ │
    +─────────────────────────────────+

2.2 Shapes 和 Layers(图形与层次)

  • 在 Artboard 内,你可以通过 Shapes(矢量图形,如矩形、圆形、路径)与 Layers(图层分组)来组织素材。
  • 每一个 Shape 都支持填充、渐变、Mask(蒙版)、裁剪路径等属性。Layers 支持 Blend Mode(混合模式)、Opacity(不透明度)等。

    Artboard: LoadingAnim
      ├─ Layer 0: Background (Rectangle shape 填充渐变)
      ├─ Layer 1: Logo (Group: Path + Mask)
      └─ Layer 2: Spinner (Ellipse shape + Stroke)

2.3 Keyframes 与 Timelines(关键帧与时间线)

  • Rive 使用 关键帧(Keyframe)在不同时间点记录属性值(位置、旋转、缩放、颜色等),并通过 Timeline 进行插值,自动填充中间帧(In-between)。
  • 在 Rive 编辑器的下方就是时间线面板,可拖动查看任意帧效果,设置缓动曲线(Linear、Ease In/Out、Custom Bézier)等。
  • Flutter 端无需关心具体时间线细节,只要调用对应 Animation Name 即可开始播放。

2.4 State Machine(状态机)

  • State Machine 是 Rive 的核心交互机制。它允许设计师在 Rive 中定义“状态”(States)与“转换”(Transitions),并基于布尔、触发器(Triggers)、数值输入(Number inputs)等逻辑驱动不同动画片段。
  • 举例:一个按钮可以有 idlehoverpressed 三个状态,设计师在 Rive 中分别制作这三段动画,并在状态机中添加条件(如 isHover == true 时从 idle 跳到 hoveronPressed 触发后跳到 pressed),这样发布成 .riv 后,Flutter 端只需控制状态机变量即可完成复杂交互动画。

    StateMachine: ButtonSM
       ┌─────────┐     onHover=true     ┌──────────┐
       │  idle   │ ──────────────────▶ │  hover   │
       └─────────┘                     └──────────┘
            ▲                                │
            │                                │ onHover=false
         onPressed                           ▼
            │                             ┌──────────┐
       ┌─────────┐                          │ pressed │
       │ pressed │ ◀──────────────────────── └──────────┘
       └─────────┘        onPressFinish(自动回到 idle)

三、快速开始:在 Flutter 中集成 Rive

3.1 准备 Rive 文件 .riv

  1. 下载安装 Rive 编辑器

    • 官网 https://rive.app/ 提供 macOS/Windows/Linux 版本。
    • 注册帐号后,新建或打开示例项目。
  2. 创建一个简单 Artboard

    • 在 Rive 编辑器中新建一个 Artboard,绘制一个图形(如旋转圆环或 Logo ),并设置简单的 “Animate” 时间线,导出成 loading.riv
  3. 导出 .riv 文件

    • 点击右上角 “Export File” 按钮,选择 “Rive File (.riv)” 并保存到项目目录下(例如 assets/animations/loading.riv)。

3.2 添加依赖与配置

pubspec.yaml 中添加 Rive Flutter Runtime 依赖,并声明 assets:

dependencies:
  flutter:
    sdk: flutter
  rive: ^0.10.0  # 请按最新版本号替换

flutter:
  assets:
    - assets/animations/loading.riv

然后运行:

flutter pub get

3.3 加载并显示静态动画

在 Flutter 代码中,只需如下步骤:

  1. 引入 Rive 包:

    import 'package:rive/rive.dart';
  2. 使用 RiveAnimation.asset(...) Widget:

    class SimpleRivePage extends StatelessWidget {
      const SimpleRivePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Rive 简单示例')),
          body: const Center(
            child: RiveAnimation.asset(
              'assets/animations/loading.riv',
              // artboard: 'LoadingScreen', // 可指定 Artboard 名称
              fit: BoxFit.contain,
            ),
          ),
        );
      }
    }
  3. 运行,屏幕中即可看到 loading.riv 中默认播放的动画(通常是第一个在 File Inspector 中勾选为 Default Animation 的 Timeline)。

四、实战示例一:播放简单动画

下面我们以一个“Loading 动画”为例,从 Rive 编辑器制作到 Flutter 代码显示,完整梳理流程。

4.1 在 Rive 编辑器中创建一个 “Loading” 动画

  1. 新建 Artboard,命名为 LoadingScreen
  2. 绘制图形:使用 Ellipse(椭圆)绘制一个圆环,设置 Stroke(描边)粗细为 8px,颜色为渐变色(可选)。
  3. 添加关键帧动画

    • 在 Timeline 面板中为 “Ellipse” 属性添加 Rotation 关键帧。例如:

      • 时间 0s:Rotation = 0
      • 时间 1s:Rotation = 360
    • 设定该 Timeline 为 “Loop” 循环模式。
    • 在右侧 File Inspector 中,勾选 “Loop Animation” 并将 Timeline 命名为 LoadingRotate
  4. 测试预览:点击 Play,可看到圆环持续旋转。
  5. 导出:File → Export → Rive File (loading.riv),保存到 Flutter 项目的 assets/animations 目录中。

4.2 Flutter 中显示动画的最简代码

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

class LoadingPage extends StatelessWidget {
  const LoadingPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Rive Loading 示例')),
      body: const Center(
        child: SizedBox(
          width: 150,
          height: 150,
          child: RiveAnimation.asset(
            'assets/animations/loading.riv',
            artboard: 'LoadingScreen',      // 指定 Artboard
            animations: ['LoadingRotate'],   // 播放指定动画
            fit: BoxFit.contain,
          ),
        ),
      ),
    );
  }
}
  • 解释

    • RiveAnimation.asset(...) 会在内部完成 rootBundle.load('...loading.riv'),并解析 .riv 文件。
    • 指定 artboardLoadingScreenanimations 数组中可列出多个 Timeline,但这里只有一个 LoadingRotate

4.3 图解:渲染流程与帧率优化

┌─────────────────────────────────────────┐
│ Flutter Frame Render (60 FPS)          │
│                                         │
│   每帧 build → RiveAnimation Widget      │
│         │                               │
│         ▼  (Rive Runtime)               │
│   RiveAnimation.asset  ──► 解码 .riv 文件  │
│         │                               │
│         ▼                               │
│   Artboard.load()                       │
│         │                               │
│         ▼  每帧 update                   │
│   Controller.advance(deltaTime)         │
│         │                               │
│         ▼  Evaluates Timeline           │
│   Graph render → Raster → GPU           │
│                                         │
└─────────────────────────────────────────┘
  • 总体思路:Rive 的 Runtime 会在 Flutter 的渲染周期内根据 deltaTime(两帧之间的时间差)计算下一帧动画状态,更新矢量图形的 Transform、颜色和路径等属性,然后通过 CustomPainter 快速绘制到 Canvas 上,最后提交给 GPU。因此只要保持场景较为简单,Flutter 端能轻松达成 60+ FPS。

五、实战示例二:State Machine 驱动交互

相比于上面的“被动播放”动画,Rive 最强大的功能在于 State Machine,可根据外部事件在不同动画状态之间切换。下面演示如何打造一个“炫酷按钮”交互。

5.1 在 Rive 中制作带有状态机的按钮动画

  1. 新建 Artboard,命名为 ButtonAnim
  2. 绘制按钮形状:使用 RoundedRectangle(圆角矩形)和 Text 组合成一个矩形按钮。
  3. 创建两段 Animation

    • Idle:默认状态,按钮颜色为淡蓝色,大小为 200×60;
    • Pressed:按下时动画,例如按钮缩小为 180×54,并颜色变为深蓝,同时文字颜色变为白色,持续 0.2 秒后返回 Idle。
  4. 添加 State Machine

    • 打开 “State Machines” 面板,创建一个新状态机 ButtonSM
    • Idle 状态下点右键 → “Add Animation” 选择 Idle Timeline;
    • 添加一个新状态 Pressed,绑定 Pressed Timeline。
    • 添加一个 Trigger 输入 pressTrigger
    • 建立 Transition (Idle → Pressed):条件为 pressTrigger == true
    • 在 Transition 的 “Exit Time” 中勾选 Use Exit Time,确保动画执行完才退出。
    • 建立 Transition (Pressed → Idle):无需条件,设定为“自动”状态(Auto Transition)在动画结束后跳到 Idle。
  5. 测试状态机:在右侧 “State Machine” 面板点击 “Play” 按钮,在 “Inputs” 区点击 pressTrigger,看按钮按下动画是否正常。

最终 .riv 文件中包含:

  • Artboard: ButtonAnim
  • Animations: Idle (循环)、Pressed (单次)
  • StateMachine: ButtonSM with input pressTrigger

5.2 Flutter 中读取 State Machine 并触发状态转换

在 Flutter 端,我们需要:

  1. 加载 .riv 文件
  2. 查找 Artboard 并 State Machine Controller
  3. 通过按钮点击触发 State Machine 的 pressTrigger
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';

class InteractiveButtonPage extends StatefulWidget {
  const InteractiveButtonPage({Key? key}) : super(key: key);

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

class _InteractiveButtonPageState extends State<InteractiveButtonPage> {
  late RiveAnimationController _btnController;
  late SMIInput<bool> _pressInput;

  @override
  void initState() {
    super.initState();
    // 1. 加载 Rive 文件并在回调中获取 State Machine Controller
    _btnController = SimpleAnimation('Idle'); // 默认先运行 Idle
    rootBundle.load('assets/animations/button.riv').then((data) async {
      final file = RiveFile.import(data);
      final artboard = file.artboardByName('ButtonAnim');
      if (artboard != null) {
        // 2. 创建 State Machine Controller
        StateMachineController? controller = StateMachineController.fromArtboard(
          artboard,
          'ButtonSM',
          onStateChange: _onStateChange,
        );
        if (controller != null) {
          artboard.addController(controller);
          // 3. 获取 Trigger Input (pressTrigger)
          _pressInput = controller.findInput<bool>('pressTrigger')!;
          setState(() {
            // 用新的 controller 替换旧的
            _btnController = controller;
          });
        }
      }
    });
  }

  // 可选:监听 Rive 状态机状态变化
  void _onStateChange(String stateMachineName, String stateName) {
    debugPrint('StateMachine $stateMachineName 切换到状态 $stateName');
  }

  @override
  void dispose() {
    _btnController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Rive 交互按钮示例')),
      body: Center(
        child: GestureDetector(
          onTap: () {
            // 4. 触发状态机输入,切换到 Pressed 状态
            _pressInput.value = true;
          },
          child: SizedBox(
            width: 200,
            height: 60,
            child: Rive(
              // 5. 直接传入 controller(已在 initState 中注入到 Artboard)
              controllers: [_btnController],
              fit: BoxFit.contain,
              // artboard 可省略,Rive 会用默认 Artboard
            ),
          ),
        ),
      ),
    );
  }
}
  • 关键步骤

    1. 使用 rootBundle.load(...) 异步加载 .riv
    2. RiveFile.import(data) 解析,获取 Artboard
    3. StateMachineController.fromArtboard(artboard, 'ButtonSM') 获取状态机控制器;
    4. 通过 controller.findInput<bool>('pressTrigger') 拿到 Trigger 类型输入,点击时赋值为 true,即触发状态转换;
    5. 将 controller 添加到 artboard 中:artboard.addController(controller),再将该 controller 传给 Rive Widget。

5.3 代码详解与图解流程

┌───────────────────────────────────────────────────────┐
│                   Flutter Widget 树                   │
│                                                       │
│ Center                                                │
│  └── GestureDetector (onTap: _pressInput.value=true)  │
│       └── SizedBox (200×60)                           │
│            └── Rive Widget (controllers: [_btnController]) │
│                                                       │
│                    ▲                                  │
│                    │                                  │
│             RiveAnimationController (_btnController)  │
│                    │                                  │
│                    │ 从 Artboard 中 update()           │
│                    ▼                                  │
│                 Artboard: ButtonAnim                  │
│                  ┌──────────────────────────────────┐ │
│                  │ StateMachineController ButtonSM  │ │
│                  │   inputs: pressTrigger           │ │
│                  │   states: Idle, Pressed          │ │
│                  └──────────────────────────────────┘ │
│                    │                                  │
│      (状态机根据 pressTrigger 触发转换 Idle→Pressed)│
│                    │                                  │
│                    ▼                                  │
│            播放 Pressed Timeline (0.2s)                │
│                    │                                  │
│            (动画结束后自动跳回 Idle)                   │
└───────────────────────────────────────────────────────┘
  • 交互流程

    1. 用户在 Flutter 侧点击按钮,onTap 设置 _pressInput.value = true
    2. Rive Runtime 在下一个 update() 周期检测到 pressTrigger == true,触发从 IdlePressed 的 Transition;
    3. 播放 Pressed Animation(缩小、变色),并自动在动画结束后通过 “Exit Time” 返回 Idle
    4. 开发者可在 _onStateChange 回调中监听状态切换,执行额外逻辑(如播放音效、触发网络请求等)。

六、高级技巧:动态修改属性 & 双向绑定

Rive 强大的地方在于不仅能播放预设动画,还能在 Flutter 侧实时修改 Rive 实例的属性,或监听 Rive 内部事件再触发 Flutter 逻辑。

6.1 通过 Flutter 代码实时修改 Rive 的属性(颜色、形状、数值)

  1. 在 Rive 中为某个 Shape 添加 “Number” 输入

    • 例如,为一个矩形的 fillColor 添加 rgba 四个数值属性(rValuegValuebValueaValue),并设定在 Timeline 中用 Keyframe 读取它们变化。
    • Rive 中 “inspector” 面板 → “Inputs” → “+” → 选择 Number → 命名为 rValue,同理添加 gValuebValueaValue
  2. 在 Flutter 中获取这些 Input

    // initState 中
    StateMachineController? controller = StateMachineController.fromArtboard(artboard, 'ColorSM');
    artboard.addController(controller!);
    SMINumber? rInput = controller.findInput<double>('rValue');
    SMINumber? gInput = controller.findInput<double>('gValue');
    SMINumber? bInput = controller.findInput<double>('bValue');
    SMINumber? aInput = controller.findInput<double>('aValue');
  3. 实时修改属性

    // 在滑块(Slider)回调中
    onChanged: (value) {
      setState(() {
        rInput?.value = value;  // value 范围 0.0 - 1.0
      });
    }
  4. Rive 中使用这些属性

    • 在 Timeline 或 Animation 中,为“Shape.Fill.Color.R”绑定 rValue 变量。这样当 rValue 改变时,下一帧 Rive 渲染时会读取最新数值。

6.2 双向绑定:监听 Rive 内部回调,触发 Flutter 逻辑

有时我们希望当 Rive 状态机切换到某个状态时,Flutter 端能收到通知。例如:动画播放到“完成”状态后弹出提示。

  1. 在 Rive 中为 State Machine 的 Transition 添加“On Entry”或“On Exit”事件,并勾选“Async Event” → onFinished 类型(可自定义名称)。
  2. 在 Flutter 端注册回调

    // initState 中
    controller = StateMachineController.fromArtboard(
      artboard,
      'MySM',
      onStateChange: _onStateChange,
    );
    ...
    void _onStateChange(String smName, String stateName) {
      if (stateName == 'Completed') {
        // Rive 中已到“Completed”状态,触发业务逻辑
        showDialog(...); // 弹出提示
      }
    }
  3. 整体图解:双向事件流

    Flutter Button 点击 ——► _pressInput.value = true ——► Rive StateMachine  
                                    │                                      │
                                    │(状态机切到 Completed)              │
                                    └──────── onStateChange 回调 ◄─────────┘
                                                    │
                                                    ▼
                                            Flutter 逻辑(弹出对话框)

七、性能优化与最佳实践

尽管 Rive 在 Flutter 中性能表现优异,但若项目中大量使用动画或多个 Rive 实例,也需要注意优化。

7.1 限制渲染区域与使用 RiveAnimationController

  • 限制渲染区域

    • 若某个 Rive Widget 在屏幕外不可见,仍会持续执行动画更新,浪费 CPU。
    • 可结合 VisibilityDetectorListView 中的 Visibility/Offstage 控制:当 Widget 不可见时调用 controller.isActive = false,停止更新。
  • 使用 RiveAnimationController 控制播放

    • SimpleAnimationStateMachineController 等都继承自 RiveAnimationController,可调用 isActive = false 暂停动画。
    • dispose() 中务必调用 controller.dispose(),避免泄露。

7.2 减少不必要的 Artboard reload

  • 不要在 build() 中频繁 RiveFile.import(...)

    • 若把解析 .riv 文件的逻辑直接写在 build() 方法里,会导致每次 setState() 重新解析,对性能伤害很大。
    • 建议在 initState() 中或使用 FutureBuilder 加载一次,保留 RiveFile/Artboard 实例,重复使用。
  • 复用同一个 Artboard 实例

    • 若多个页面需要展示相同动画,尽量传递同一个 Artboard 或 Controller,并在切换页面时仅切换 isActive,而非重新导入 .riv

7.3 AOT 下动态加载与预缓存

  • AOT 模式打包体积

    • Rive Runtime 自带一部分 C++ 解析库,在 AOT 模式下会被打包进 libapp.so。若频繁动态加载,会略微增加 APK 大小,但对于较小的 .riv 文件影响不大。
  • 预缓存常用动画

    • 对于启动页动画或常用交互,可在 App 启动时调用一次 RiveFile.import(...),并缓存结果到全局单例,这样后续再创建 Rive Widget 时,只需从缓存拿到已解析的 ArtboardRiveFile
    • 配合 FutureBuilderProvider 管理,避免动画首次加载出现延迟。

八、总结与扩展思考

  1. Rive 优势回顾

    • 可视化动画创作:设计师可在编辑器中实时调参、预览;
    • 实时交互状态机:支持复杂条件触发、双向交互;
    • 高性能:基于 Flutter Canvas 矢量渲染,支持 60 FPS 或更高帧率;
  2. Flutter 与 Rive 的典型使用场景

    • 启动页 / Loading:优雅的加载指示;
    • 交互动效按钮 / 图标微动:按下、切换状态、Tab 栏选中等;
    • 游戏 UI / 角色动画:在小型游戏或卡通风格 App 中,角色跑跳、场景动画;
    • 数据可视化:动态图表中嵌入交互动效,例如 Data Dashboard 中的折线图动画。
  3. 未来扩展方向

    • 与 Flutter 的自定义 Shader 结合:通过自定义 CustomPainter 在 Rive 渲染后再加上 Shader 效果,实现更炫酷的光影或粒子特效。
    • 混合平台:Rive 支持 Web、iOS、Android,此时可将相同 .riv 文件用于 Flutter Web 与移动端,实现动画统一。
    • 代码生成:考虑将 Rive Animation Controller 代码自动生成,减少手写拼接逻辑,提高可维护性。

至此,你已掌握从零开始在 Flutter 中使用 Rive 的“炫酷交互”全流程,包括:

  • Rive 核心概念与术语;
  • 在 Flutter 中加载并播放简单动画;
  • 使用 State Machine 实现复杂交互;
  • 动态修改属性与双向绑定;
  • 一系列性能优化与最佳实践。
最后修改于:2025年06月03日 14:55

评论已关闭

推荐阅读

DDPG 模型解析,附Pytorch完整代码
2024年11月24日
DQN 模型解析,附Pytorch完整代码
2024年11月24日
AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日