Flutter健身工作流插件flutter_workoutkit的使用
Flutter健身工作流插件flutter_workoutkit的使用
注意:此插件仅适用于iOS 17.0及以上设备,并且需要与iOS设备配对的Apple Watch。不支持Android设备。
一个利用Apple的WorkoutKit SDK来创建、预览和同步自定义运动的Flutter插件。该插件使Flutter应用与WatchOS的运动功能无缝集成,允许开发者通过编程方式定义和管理用户可以直接在Apple Watch上访问的运动计划。
🚨 积极开发中!
该插件目前处于积极开发阶段。可能会有破坏性更改,直到版本1.0.0发布。在生产环境中使用此插件时请自行承担风险。如有任何问题或功能请求,请在GitHub仓库中报告。
🔑 关键特性
- 创建、预览和同步自定义运动。
- 使用小部件定义自定义、单目标、配速或游泳骑行跑步的运动计划。
- 设置每个运动步骤的目标,例如时间、距离或重复次数。
- 设置各种警报,如心率区间、配速和功率区间。
- 与Apple Watch上的运动应用完美配合。
🎥 预览

📸 截图


📝 示例运动
final CustomWorkout speedCyclingWorkout = CustomWorkout(
activityType: WorkoutActivityType.cycling,
location: WorkoutLocationType.outdoor,
displayName: "Speed Cycling",
warmup: WorkoutStep(
alert: HeartRateZoneAlert(zone: 1),
goal: const WorkoutGoal(
type: WorkoutGoalType.time,
targetDuration: Duration(minutes: 10),
unit: WorkoutGoalUnit.minutes,
),
),
blocks: [
IntervalBlock(
type: IntervalBlockType.work,
iterations: 1,
steps: [
IntervalStep(
alert: SpeedRangeAlert(
lowerBound: 28,
upperBound: 32,
unitSpeed: UnitSpeed.kilometersPerHour,
metric: WorkoutAlertMetric.average,
),
purpose: IntervalStepPurpose.work,
goal: const WorkoutGoal(
type: WorkoutGoalType.distance,
targetValue: 24,
unit: WorkoutGoalUnit.kilometers,
),
),
],
),
],
cooldown: WorkoutStep(
alert: HeartRateZoneAlert(zone: 1),
goal: const WorkoutGoal(
type: WorkoutGoalType.time,
targetDuration: Duration(minutes: 10),
unit: WorkoutGoalUnit.minutes,
),
),
);
📥 安装
在您的Flutter项目中的pubspec.yaml
文件内添加flutter_workoutkit
作为依赖项:
dependencies:
flutter_workoutkit: <latest_version>
此插件需要在项目中启用HealthKit。确保在Info.plist
文件中有必要的权限:
<key>NSHealthShareUsageDescription</key>
<string>允许访问健康数据以跟踪运动。</string>
<key>NSHealthUpdateUsageDescription</key>
<string>允许更新健康数据以跟踪运动。</string>
同时,确保在Xcode项目中启用了必要的功能:

📚 使用
您可以使用四种运动类之一来定义运动:
CustomWorkout
PacerWorkout
SwimBikeRunWorkout
SingleGoalWorkout
您可以在插件包内的lib/sampleWorkouts
文件夹或示例应用中查看每种运动的预览示例。
要预览并同步运动,可以使用WorkoutPreviewButton
小部件:
WorkoutPreviewButton(workout: speedCyclingWorkout);
WorkoutPreviewButton
小部件会自动调用原生的workoutPreview()
方法来预览运动,并允许用户将运动保存到他们的Apple Watch。
在预览运动之前,必须请求健康权限:
import 'package:flutter_workoutkit/flutter_workoutkit.dart';
await Workoutkit.hasHealthPermissions();
await Workoutkit.requestHealthPermissions();
🎨 自定义预览按钮
WorkoutKit框架当前只提供了触发运动预览模态窗口的原生按钮。没有API可以实现无用户交互地预览运动。
为了适应这一限制,该插件提供了一个WorkoutPreviewButton
小部件,用于渲染原生iOS按钮。因此,目前对按钮的定制是有限的。请检查WorkoutPreviewButton
小部件以获取可用的定制选项。
🚧 路线图
- ✅ 添加支持
WorkoutPreviewButton
来预览运动 - ✅ 添加基本定制选项给
WorkoutPreviewButton
小部件 - ❌ 添加更多高级定制选项给
WorkoutPreviewButton
小部件 - ❌ 添加支持
WorkoutScheduler
来安排和管理运动 - ❌ 添加支持
ScheduledWorkoutPlan
来安排运动计划 - ❌ 添加支持
poolSwimDistanceWithTime
来设置运动目标 - ❌ 改进示例和示例应用
- ❌ 改进文档
- ❌ 添加测试
- ❌ (长期)探索支持Android的选项
📝 许可证
该项目由Apache License 2.0许可。详情请参阅LICENSE文件。
📧 联系
如有问题或反馈,请联系我:a@adamkramer.dev
💰 请我喝杯咖啡
如果您觉得这个插件有用,请考虑买杯咖啡支持我:
示例代码
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_workoutkit/flutter_workoutkit.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
bool _hasHealthPermissions = false;
[@override](/user/override)
void initState() {
super.initState();
initPlatformState();
}
// 平台消息异步,因此我们初始化在一个异步方法中。
Future<void> initPlatformState() async {
String platformVersion;
try {
platformVersion =
await Workoutkit.getPlatformVersion() ?? '未知平台版本';
} on PlatformException {
platformVersion = '无法获取平台版本。';
}
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter WorkoutKit 示例'),
),
body: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: ElevatedButton(
onPressed: () => Workoutkit.requestHealthPermissions(),
child: const Text('请求健康权限'),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: ElevatedButton(
onPressed: () =>
Workoutkit.hasHealthPermissions().then((value) {
setState(() {
_hasHealthPermissions = value;
});
}),
child: const Text('检查健康权限'),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text('是否有健康权限: $_hasHealthPermissions'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Center(
child: Text('运行于: $_platformVersion\n'),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sampleSwimBikeRunWorkout,
buttonTitle: '[SwimBikeRun] 三项全能训练'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: samplePacerHoursWorkout,
buttonTitle: '[Pacer] 2 小时骑行'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: samplePacerMinutesWorkout,
buttonTitle: '[Pacer] 30 分钟跑步'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sampleSpeedCyclingWorkout,
buttonTitle: '[Custom] 速度骑行'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sampleCustomWorkout,
buttonTitle: '[Custom] 定时运动'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sample10kTrainingRun,
buttonTitle: '[Custom] 10公里训练跑'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sample21kmTrainingRun,
buttonTitle: '[Custom] 21公里分段跑'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sampleSingleGoalTimedWorkout,
buttonTitle: '[Single] 定时运动'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sampleSingleGoalEnergyWorkout,
buttonTitle: '[Single] 能量运动'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sampleSingleOpenWorkout,
buttonTitle: '[Single] 开放式运动'),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: WorkoutPreviewButton(
workout: sampleSingleGoalSwimmingWorkout,
buttonTitle: '[Single] 游泳运动'),
),
],
),
),
],
),
),
);
}
}
更多关于Flutter健身工作流插件flutter_workoutkit的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter健身工作流插件flutter_workoutkit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter健身工作流插件 flutter_workoutkit
的示例代码。这个插件通常用于管理和跟踪健身锻炼,包括创建锻炼计划、记录锻炼进度等功能。
首先,确保你已经在你的 pubspec.yaml
文件中添加了 flutter_workoutkit
依赖:
dependencies:
flutter:
sdk: flutter
flutter_workoutkit: ^最新版本号 # 请替换为最新的版本号
然后运行 flutter pub get
来获取依赖。
以下是一个简单的示例代码,展示如何使用 flutter_workoutkit
来创建一个锻炼计划并启动锻炼:
import 'package:flutter/material.dart';
import 'package:flutter_workoutkit/flutter_workoutkit.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter WorkoutKit Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: WorkoutScreen(),
);
}
}
class WorkoutScreen extends StatefulWidget {
@override
_WorkoutScreenState createState() => _WorkoutScreenState();
}
class _WorkoutScreenState extends State<WorkoutScreen> {
late WorkoutManager _workoutManager;
@override
void initState() {
super.initState();
// 初始化WorkoutManager
_workoutManager = WorkoutManager();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter WorkoutKit Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 创建一个锻炼计划
_createWorkoutPlan();
},
child: Text('Create Workout Plan'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// 启动锻炼
_startWorkout();
},
child: Text('Start Workout'),
),
],
),
),
);
}
void _createWorkoutPlan() {
// 创建一个锻炼集合
List<Exercise> exercises = [
Exercise(
name: 'Push-Ups',
sets: 3,
reps: 12,
restTime: Duration(seconds: 30),
),
Exercise(
name: 'Squats',
sets: 3,
reps: 15,
restTime: Duration(seconds: 30),
),
// 添加更多锻炼...
];
// 创建锻炼计划
WorkoutPlan plan = WorkoutPlan(
name: 'Daily Workout',
exercises: exercises,
);
// 将计划添加到WorkoutManager中(假设插件支持这种操作,具体根据文档实现)
// 注意:实际插件API可能不同,这里仅为示例
_workoutManager.addPlan(plan);
// 显示一个SnackBar通知用户计划已创建
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Workout plan created successfully!'),
),
);
}
void _startWorkout() {
// 假设我们已有一个计划要启动
// WorkoutPlan plan = _workoutManager.getPlanByName('Daily Workout');
// 注意:实际插件API可能不同,这里仅为示例
// 启动锻炼(具体实现依赖于插件提供的API)
// _workoutManager.startWorkout(plan);
// 由于我们不知道插件的确切API,这里仅显示一个SnackBar作为示例
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Workout started!'),
),
);
}
}
// 假设的Exercise类定义(根据插件实际要求调整)
class Exercise {
String name;
int sets;
int reps;
Duration restTime;
Exercise({required this.name, required this.sets, required this.reps, required this.restTime});
}
// 假设的WorkoutPlan类定义(根据插件实际要求调整)
class WorkoutPlan {
String name;
List<Exercise> exercises;
WorkoutPlan({required this.name, required this.exercises});
}
// 注意:上述Exercise和WorkoutPlan类仅为示例,实际使用时需要根据flutter_workoutkit插件的文档进行调整。
// 同时,WorkoutManager及其方法(如addPlan和startWorkout)也是假设的,实际API可能不同。
重要提示:
- 由于
flutter_workoutkit
插件的具体API和实现细节可能与我提供的示例代码不同,因此你需要查阅该插件的官方文档来了解如何正确初始化、添加锻炼计划和启动锻炼。 - 上述代码中的
Exercise
和WorkoutPlan
类是假设的,仅用于演示目的。你需要根据插件的实际数据结构进行调整。 - 插件的
WorkoutManager
类及其方法(如addPlan
和startWorkout
)也是假设的,实际使用时请参考插件的API文档。
希望这个示例代码能帮助你入门如何使用 flutter_workoutkit
插件。如果你有更多具体问题或需要进一步的帮助,请查阅插件的官方文档或提出更详细的问题。