Files
xianyan/lib/core/layout/rive_tab_icon.dart
Developer ca68fe29c7 chore: 批量整理优化项目代码与配置
- 新增模型目录占位文件与翻译类型拆分
- 调整路由配置与桌面端窗口初始化
- 移除多处冗余图表配置项
- 重构右侧面板注册表与三栏布局组件
- 添加智能AppBar、拖拽书签等新功能组件
- 优化安卓编译配置与多平台插件注册
- 新增翻译覆盖率测试与共享组件
- 格式化代码与修复静态分析警告
2026-05-29 10:08:02 +08:00

99 lines
2.6 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/// ============================================================
/// 闲言APP — Rive Tab 动画组件
/// 创建时间: 2026-05-29
/// 更新时间: 2026-05-29
/// 作用: 使用Rive动画替代TabIconSprite实现更丰富的角色动画
/// 上次更新: 初始创建
/// ============================================================
import 'package:flutter/cupertino.dart';
import 'package:rive/rive.dart';
/// Rive Tab 动画图标组件
///
/// 通过 Rive StateMachine 控制选中/未选中状态切换,
/// 作为 TabIconSprite 的可选替代方案。
/// 需要提供 .riv 资源文件StateMachine 中需包含
/// 名为 `isSelected` 的布尔输入。
class RiveTabIcon extends StatefulWidget {
const RiveTabIcon({
required this.isSelected,
required this.assetPath,
this.stateMachineName = 'State',
this.size = 32,
super.key,
});
/// 是否选中
final bool isSelected;
/// Rive 资源路径 (如 'assets/animations/tab_home.riv')
final String assetPath;
/// StateMachine 名称
final String stateMachineName;
/// 图标尺寸
final double size;
@override
State<RiveTabIcon> createState() => _RiveTabIconState();
}
class _RiveTabIconState extends State<RiveTabIcon> {
SMIInput<bool>? _selectedInput;
Artboard? _artboard;
@override
void initState() {
super.initState();
_loadRive();
}
/// 加载 Rive 文件并初始化 StateMachine
Future<void> _loadRive() async {
try {
final data = await RiveFile.asset(widget.assetPath);
final artboard = data.mainArtboard;
final controller = StateMachineController.fromArtboard(
artboard,
widget.stateMachineName,
);
if (controller != null) {
artboard.addController(controller);
_selectedInput = controller.findInput<bool>('isSelected');
_selectedInput?.value = widget.isSelected;
}
if (mounted) {
setState(() => _artboard = artboard);
}
} catch (e) {
// Rive文件加载失败时静默处理不影响其他功能
}
}
@override
void didUpdateWidget(RiveTabIcon oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.isSelected != widget.isSelected) {
_selectedInput?.value = widget.isSelected;
}
}
@override
Widget build(BuildContext context) {
if (_artboard == null) {
return SizedBox(
width: widget.size,
height: widget.size,
child: const CupertinoActivityIndicator(radius: 8),
);
}
return SizedBox(
width: widget.size,
height: widget.size,
child: Rive(artboard: _artboard!),
);
}
}