Flutter后台高强度间歇训练(HIIT)计时器插件background_hiit_timer的使用
Flutter后台高强度间歇训练(HIIT)计时器插件 background_hiit_timer
的使用
概述
background_hiit_timer
是一个用于创建高强度间歇训练(HIIT)计时器的Flutter插件,支持后台服务功能。它最初为 OpenHIIT 创建。
目录
安装
在你的 pubspec.yaml
文件中添加 background_hiit_timer
:
dependencies:
flutter:
sdk: flutter
background_hiit_timer: ^1.0.0
基本用法
导入包
在你的 Dart 文件中导入 background_hiit_timer
:
import 'package:background_hiit_timer/background_hiit_timer.dart';
配置步骤
- 确保你的应用正确配置了 Android 和 iOS 平台的后台执行。参考 flutter_background_service 获取详细信息。
- 定义一组间隔时间(intervals):
final List<IntervalType> intervals = [
IntervalType(
id: "0",
workoutId: "1",
time: 10, // in seconds
name: "Get ready",
color: 0,
intervalIndex: 0,
startSound: "",
halfwaySound: "",
countdownSound: "countdown-beep",
endSound: ""),
IntervalType(
id: "4",
workoutId: "1",
time: 10, // in seconds
name: "Cooldown",
color: 0,
intervalIndex: 4,
startSound: "long-rest-beep",
countdownSound: "countdown-beep",
endSound: "horn",
halfwaySound: ""),
];
- 定义控制器:
final CountdownController _controller = CountdownController(autoStart: true);
- 创建
Countdown
小部件并配置其间隔设置:
Countdown(
controller: _controller,
intervals: intervals,
onFinished: () {},
build: (_, TimerState timerState) {
return Text(timerState.currentMicroSeconds.toString());
}
)
示例用法
以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 background_hiit_timer
插件:
import 'package:audio_session/audio_session.dart';
import 'package:background_hiit_timer/models/interval_type.dart';
import 'package:background_hiit_timer/models/timer_state.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:background_hiit_timer/background_timer.dart';
import 'package:background_hiit_timer/background_timer_controller.dart';
Future<void> main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Countdown Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Countdown'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({Key? key, required this.title}) : super(key: key);
@override
MyHomePageState createState() => MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
final CountdownController _controller = CountdownController(autoStart: true);
List<int> listItems = [];
List<int> removedItems = [];
bool _paused = false;
bool _changeVolume = false;
double _volume = .8;
late SharedPreferences prefs;
final List<IntervalType> intervals = [
IntervalType(
id: "0",
workoutId: "1",
time: 5,
name: "Get ready",
color: 0,
intervalIndex: 0,
startSound: "",
halfwaySound: "",
countdownSound: "countdown-beep",
endSound: ""),
IntervalType(
id: "1",
workoutId: "1",
time: 5,
name: "Warmup",
color: 0,
intervalIndex: 1,
startSound: "long-bell",
halfwaySound: "",
countdownSound: "countdown-beep",
endSound: ""),
IntervalType(
id: "2",
workoutId: "1",
time: 5,
name: "Work",
color: 0,
intervalIndex: 2,
startSound: "long-bell",
halfwaySound: "short-halfway-beep",
countdownSound: "countdown-beep",
endSound: ""),
IntervalType(
id: "3",
workoutId: "1",
time: 5,
name: "Rest",
color: 0,
intervalIndex: 3,
startSound: "long-rest-beep",
halfwaySound: "",
countdownSound: "countdown-beep",
endSound: ""),
IntervalType(
id: "4",
workoutId: "1",
time: 5,
name: "Cooldown",
color: 0,
intervalIndex: 4,
startSound: "long-rest-beep",
countdownSound: "countdown-beep",
endSound: "horn",
halfwaySound: ""),
];
static const Map<String, Color> intervalColors = {
"Work": Colors.green,
"Rest": Colors.red,
"Get ready": Colors.black,
"Warmup": Colors.orange,
"Cooldown": Colors.blue,
"End": Colors.purple,
};
@override
void initState() {
super.initState();
initializeAudioSession();
loadPreferences();
listItems = intervals.map((interval) => interval.intervalIndex).toList();
}
Future<void> initializeAudioSession() async {
final session = await AudioSession.instance;
await session.configure(const AudioSessionConfiguration(
avAudioSessionCategory: AVAudioSessionCategory.playback,
avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.mixWithOthers,
avAudioSessionMode: AVAudioSessionMode.defaultMode,
avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.defaultPolicy,
avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
androidAudioAttributes: AndroidAudioAttributes(
contentType: AndroidAudioContentType.sonification,
flags: AndroidAudioFlags.audibilityEnforced,
usage: AndroidAudioUsage.notification,
),
androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
androidWillPauseWhenDucked: true,
));
await session.setActive(true);
}
Future<void> loadPreferences() async {
prefs = await SharedPreferences.getInstance();
setState(() {
_volume = prefs.getDouble('volume') ?? .8;
_changeVolume = prefs.getBool('changeVolume') ?? false;
});
}
Future<void> toggleVolumeSlider() async {
setState(() {
_changeVolume = !_changeVolume;
});
await prefs.setBool('changeVolume', _changeVolume);
}
Future<void> togglePause() async {
setState(() {
_paused = !_paused;
});
_paused ? _controller.pause() : _controller.resume();
}
Color getBackgroundColor(String status) =>
intervalColors[status] ?? const Color.fromARGB(255, 0, 225, 255);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Countdown(
controller: _controller,
intervals: intervals,
onFinished: () {},
build: (_, TimerState timerState) {
while (listItems.length + timerState.currentInterval > intervals.length) {
removedItems.add(listItems[0]);
listItems.removeAt(0);
}
while (listItems.length + timerState.currentInterval < intervals.length) {
listItems.insert(0, removedItems[removedItems.length - 1]);
removedItems.removeAt(removedItems.length - 1);
}
return Container(
color: getBackgroundColor(timerState.status),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(timerState.status,
style: const TextStyle(fontSize: 50, color: Colors.white)),
Text(
(timerState.currentMicroSeconds /
const Duration(seconds: 1).inMicroseconds)
.round()
.toString(),
style: const TextStyle(fontSize: 100, color: Colors.white)),
SizedBox(
height: 220,
child: ListView.builder(
itemCount: listItems.length,
itemBuilder: (context, index) {
return Container(
color: const Color.fromARGB(64, 0, 0, 0),
child: ListTile(
title: Text(
intervals[listItems[index]].name,
style: const TextStyle(color: Colors.white),
),
));
},
),
)
],
),
);
},
),
);
}
}
高级配置
查看 高级配置文档 获取更多信息。
贡献
行为准则
在贡献时,请牢记 行为准则。
致谢
这个包受到了 timer_count_down 包的启发。
感谢 flutter_background_service 让后台计时器成为可能。
许可证
MIT 许可证。详情请参见 LICENSE。
更多关于Flutter后台高强度间歇训练(HIIT)计时器插件background_hiit_timer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter后台高强度间歇训练(HIIT)计时器插件background_hiit_timer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中集成和使用background_hiit_timer
插件的一个示例代码案例。这个插件假设是用于在后台运行高强度间歇训练(HIIT)计时器的。由于这是一个假设的插件,具体实现细节可能会有所不同,但我会提供一个通用的代码框架来展示如何集成和使用这样的插件。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加background_hiit_timer
依赖:
dependencies:
flutter:
sdk: flutter
background_hiit_timer: ^latest_version # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置Android和iOS后台权限
为了确保插件能在后台运行,你可能需要在Android和iOS项目中配置相应的权限。具体步骤取决于插件的要求,但通常包括在AndroidManifest.xml
中添加权限声明和在iOS的Info.plist
中添加后台模式支持。
3. 初始化插件并设置HIIT计时器
在你的Flutter应用中,你可以按照以下方式初始化插件并设置HIIT计时器:
import 'package:flutter/material.dart';
import 'package:background_hiit_timer/background_hiit_timer.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('HIIT Timer Demo'),
),
body: Center(
child: HIITTimerButton(),
),
),
);
}
}
class HIITTimerButton extends StatefulWidget {
@override
_HIITTimerButtonState createState() => _HIITTimerButtonState();
}
class _HIITTimerButtonState extends State<HIITTimerButton> {
BackgroundHIITTimer? _hiitTimer;
@override
void initState() {
super.initState();
// 初始化插件
_hiitTimer = BackgroundHIITTimer();
// 配置HIIT计时器,例如:30秒工作,15秒休息,共4轮
_hiitTimer?.configure(
workIntervals: [30000], // 工作时间,单位毫秒
restIntervals: [15000], // 休息时间,单位毫秒
rounds: 4, // 轮数
);
// 监听计时器状态变化
_hiitTimer?.statusStream.listen((status) {
print('HIIT Timer Status: $status');
// 你可以在这里更新UI或执行其他操作
});
}
@override
void dispose() {
_hiitTimer?.dispose();
super.dispose();
}
void _startTimer() {
_hiitTimer?.start();
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: _startTimer,
child: Text('Start HIIT Timer'),
);
}
}
4. 注意事项
- 后台执行限制:在iOS上,后台执行受到严格限制。你可能需要申请特定的后台模式,如音频播放、位置更新等,以保持应用在后台运行。
- 电池优化:后台运行会消耗电池,确保你的应用有合理的电池使用策略,避免不必要的后台活动。
- 权限处理:在Android上,确保你的应用有必要的权限来处理后台任务,如访问网络、保持CPU唤醒等。
5. 测试和调试
在实际部署之前,务必在真实设备上进行充分的测试和调试,以确保后台计时器按预期工作。
请注意,由于background_hiit_timer
是一个假设的插件,实际使用时需要参考具体插件的文档和API进行集成。如果这样的插件不存在,你可能需要自己实现后台计时器功能,或者寻找类似的第三方库。