Flutter动画开关插件reactive_animated_toggle_switch的使用
Flutter动画开关插件reactive_animated_toggle_switch的使用
reactive_animated_toggle_switch
是一个基于 animated_toggle_switch
的包装库,可以与 reactive_forms
结合使用。目前文档还在编写中,可以查看 example
文件夹中的示例代码来了解如何使用。
示例代码
import 'package:flutter/material.dart';
import 'package:reactive_animated_toggle_switch/reactive_animated_toggle_switch.dart';
import 'package:reactive_forms/reactive_forms.dart';
// 自定义图标生成器
Widget rollingIconBuilder(int? value, bool foreground) {
return Icon(iconDataByValue(value));
}
// 根据值返回对应的图标数据
IconData iconDataByValue(int? value) => switch (value) {
0 => Icons.access_time_rounded,
1 => Icons.check_circle_outline_rounded,
2 => Icons.power_settings_new_rounded,
_ => Icons.lightbulb_outline_rounded,
};
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// 构建表单
FormGroup buildForm() => fb.group({
'rolling': FormControl<int>(value: 2),
'size': FormControl<int>(value: 2),
'dual': FormControl<bool>(value: false),
'custom': FormControl<bool>(value: false),
});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(),
body: SafeArea(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.symmetric(
horizontal: 20.0,
vertical: 20.0,
),
child: ReactiveFormBuilder(
form: buildForm,
builder: (context, form, child) {
return Column(
children: [
// 滚动类型的动画开关
ReactiveAnimatedToggleSwitchRolling<int, int>(
formControlName: 'rolling',
values: const [0, 1, 2, 3],
iconBuilder: rollingIconBuilder,
),
// 自定义样式的动画开关
ReactiveCustomAnimatedToggleSwitch<bool, bool>(
formControlName: 'custom',
values: const [false, true],
spacing: 0.0,
indicatorSize: const Size.square(30.0),
animationDuration: const Duration(milliseconds: 200),
animationCurve: Curves.linear,
iconBuilder: (context, local, global) {
return const SizedBox();
},
cursors: const ToggleCursors(
defaultCursor: SystemMouseCursors.click,
),
iconsTappable: false,
wrapperBuilder: (context, global, child) {
return Stack(
alignment: Alignment.center,
children: [
Positioned(
left: 10.0,
right: 10.0,
height: 20.0,
child: DecoratedBox(
decoration: BoxDecoration(
color: Color.lerp(
Colors.black26,
Theme.of(context).colorScheme.background,
global.position,
),
borderRadius: const BorderRadius.all(
Radius.circular(50.0),
),
),
),
),
child,
],
);
},
foregroundIndicatorBuilder: (context, global) {
return SizedBox.fromSize(
size: global.indicatorSize,
child: DecoratedBox(
decoration: BoxDecoration(
color: Color.lerp(
Colors.white,
Theme.of(context).primaryColor,
global.position,
),
borderRadius: const BorderRadius.all(
Radius.circular(50.0),
),
boxShadow: const [
BoxShadow(
color: Colors.black38,
spreadRadius: 0.05,
blurRadius: 1.1,
offset: Offset(0.0, 0.8),
)
],
),
),
);
},
),
// 自定义大小的动画开关
ReactiveAnimatedToggleSwitchSize<int, int>(
formControlName: 'size',
style: ToggleStyle(
backgroundColor: const Color(0xFF919191),
indicatorColor: const Color(0xFFEC3345),
borderColor: Colors.transparent,
borderRadius: BorderRadius.circular(10.0),
indicatorBorderRadius: BorderRadius.zero,
),
values: const [0, 1, 2],
iconOpacity: 1.0,
selectedIconScale: 1.0,
indicatorSize: const Size.fromWidth(100),
iconAnimationType: AnimationType.onHover,
styleAnimationType: AnimationType.onHover,
spacing: 2.0,
customSeparatorBuilder: (context, local, global) {
final opacity = ((global.position - local.position).abs() - 0.5).clamp(0.0, 1.0);
return VerticalDivider(
indent: 10.0,
endIndent: 10.0,
color: Colors.white38.withOpacity(opacity));
},
customIconBuilder: (context, local, global) {
final text = const ['not', 'only', 'icons'][local.index];
return Center(
child: Text(text,
style: TextStyle(
color: Color.lerp(Colors.black, Colors.white, local.animationValue))));
},
borderWidth: 0.0,
),
// 双按钮动画开关
ReactiveAnimatedToggleSwitchDual<bool, bool>(
formControlName: 'dual',
first: false,
second: true,
spacing: 50.0,
style: const ToggleStyle(
borderColor: Colors.transparent,
boxShadow: [
BoxShadow(
color: Colors.black26,
spreadRadius: 1,
blurRadius: 2,
offset: Offset(0, 1.5),
),
],
),
borderWidth: 5.0,
height: 55,
styleBuilder: (b) => ToggleStyle(
indicatorColor: b ? Colors.red : Colors.green),
iconBuilder: (value) => value
? const Icon(Icons.coronavirus_rounded)
: const Icon(Icons.tag_faces_rounded),
textBuilder: (value) => value
? const Center(child: Text('Oh no...'))
: const Center(child: Text('Nice :)')),
),
// 提交按钮
ElevatedButton(
child: const Text('Submit'),
onPressed: () {
if (form.valid) {
debugPrint(form.value.toString());
}
},
),
],
);
},
),
),
),
),
);
}
}
更多关于Flutter动画开关插件reactive_animated_toggle_switch的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动画开关插件reactive_animated_toggle_switch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何使用reactive_animated_toggle_switch
插件的Flutter代码示例。这个插件提供了一个带有动画效果的开关组件,非常适合在用户界面中展示开关状态。
首先,确保你已经在pubspec.yaml
文件中添加了reactive_animated_toggle_switch
依赖:
dependencies:
flutter:
sdk: flutter
reactive_animated_toggle_switch: ^2.0.0 # 请检查最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,是一个完整的Flutter应用示例,展示了如何使用ReactiveAnimatedToggleSwitch
:
import 'package:flutter/material.dart';
import 'package:reactive_animated_toggle_switch/reactive_animated_toggle_switch.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ToggleSwitchNotifier()),
],
child: MaterialApp(
title: 'Reactive Animated Toggle Switch Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
),
);
}
}
class ToggleSwitchNotifier with ChangeNotifier {
bool isSwitchedOn = false;
void toggleSwitch() {
isSwitchedOn = !isSwitchedOn;
notifyListeners();
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final toggleSwitchNotifier = context.watch<ToggleSwitchNotifier>();
return Scaffold(
appBar: AppBar(
title: Text('Reactive Animated Toggle Switch Demo'),
),
body: Center(
child: ReactiveAnimatedToggleSwitch.multipleValues<bool>(
values: [toggleSwitchNotifier.isSwitchedOn],
activeColor: Colors.green,
inactiveColor: Colors.grey,
inactiveThumbColor: Colors.white,
activeThumbColor: Colors.white,
size: 50.0,
onToggle: (index, value) {
toggleSwitchNotifier.toggleSwitch();
},
labels: ReactiveToggleSwitchLabel.both(
onLabel: Text('ON'),
offLabel: Text('OFF'),
),
),
),
),
);
}
}
代码解释:
-
依赖注入和状态管理:
- 使用
provider
包来管理开关的状态。ToggleSwitchNotifier
类包含一个布尔值isSwitchedOn
,并提供了一个toggleSwitch
方法来切换该值。
- 使用
-
UI构建:
MyApp
类设置了MaterialApp
,并使用MultiProvider
来提供ToggleSwitchNotifier
实例。MyHomePage
类构建了一个简单的UI,包含一个ReactiveAnimatedToggleSwitch
组件。
-
ReactiveAnimatedToggleSwitch:
values
属性接受一个布尔值列表,这里只有一个值toggleSwitchNotifier.isSwitchedOn
。activeColor
和inactiveColor
分别设置开关激活和未激活时的背景颜色。inactiveThumbColor
和activeThumbColor
设置开关拇指(滑块)的颜色。size
属性设置开关的大小。onToggle
回调在开关状态改变时被调用,这里用来调用toggleSwitchNotifier
的toggleSwitch
方法。labels
属性设置开关的标签,ReactiveToggleSwitchLabel.both
方法允许同时显示“ON”和“OFF”标签。
这个示例展示了如何使用reactive_animated_toggle_switch
插件来创建一个具有动画效果的开关,并结合provider
包来管理开关的状态。你可以根据需要进一步自定义开关的样式和行为。