如何通过 flutter_bloc 库使用 BLoC 模式?
How to use BLoC pattern via flutter_bloc library?
我正在使用 Flutter 编写一个小型电子鸡应用,现在我正在学习如何使用 flutter_bloc 库。
当用户点击屏幕上的宠物图像时,它必须重新绘制 CircularPercentIndicator 小部件,但它不会起作用。我正在尝试使用 BlocBuilder 和 BlocProvider classes 将视图与 bloc 连接起来,但它没有帮助。
点击宠物widget后,动画被转发,但是saturationCount和CircularPercentIndicator的状态还没有更新。
这是我的宠物喂养 BLoC:
class PetFeedingBloc extends Bloc<SaturationEvent, SaturationState> {
PetFeedingBloc()
: super(const SaturationState(saturationCount: 40.0)) {
on<SaturationSmallIncrementEvent>((event, emit) => state.saturationCount + 15.0);
on<SaturationBigIncrementEvent>((event, emit) => state.saturationCount + 55.0);
on<SaturationDecrementEvent>((event, emit) => state.saturationCount - 2.0);
}
}
在 SaturationBarWidget 中 class 我正在尝试将小部件中的百分比指示器与 BLoC 连接,但它不起作用。这是:
class SaturationBarWidget extends StatefulWidget {
const SaturationBarWidget({Key? key}) : super(key: key);
@override
State<SaturationBarWidget> createState() => SaturationBarWidgetState();
}
class SaturationBarWidgetState extends State<SaturationBarWidget> {
@override
void initState() {
Timer? timer;
timer = Timer.periodic(const Duration(milliseconds: 3000), (_) {
setState(() {
context.read<PetFeedingBloc>().add(SaturationDecrementEvent());
if (context.read<PetFeedingBloc>().state.saturationCount <= 0) {
timer?.cancel();
}
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return BlocBuilder<PetFeedingBloc, SaturationState>(builder: (context, state){
return CircularPercentIndicator(
radius: 50.0,
lineWidth: 20.0,
animateFromLastPercent: true,
percent: context.read<PetFeedingBloc>().state.saturationCount / 100,
center: const Icon(
Icons.emoji_emotions_outlined,
size: 50.0,
),
backgroundColor: Colors.blueGrey,
progressColor: Colors.blue,
);
});
}
}
这里是我的 PetWidget class,需要点击图片:
class PetWidget extends StatefulWidget {
const PetWidget({Key? key}) : super(key: key);
@override
State<PetWidget> createState() => PetWidgetState();
}
class PetWidgetState extends State<PetWidget> with TickerProviderStateMixin {
late Animation<Offset> _animation;
late AnimationController _animationController;
static GlobalKey<SaturationBarWidgetState> key = GlobalKey();
bool reverse = true;
Image cat = Image.asset('images/cat.png');
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 4));
_animation = Tween<Offset>(begin: Offset.zero, end: const Offset(1, 0))
.animate(CurvedAnimation(
parent: _animationController, curve: Curves.elasticIn));
_animationController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animationController.reverse();
}
});
//_animationController.forward();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(child:
BlocBuilder<PetFeedingBloc, SaturationState>(builder: (context, state) {
return Center(
child: SizedBox(
width: 300,
height: 400,
child: SlideTransition(
position: _animation,
child: GestureDetector(
child: cat,
onDoubleTap: () {
context.read<PetFeedingBloc>().add(SaturationBigIncrementEvent());
_animationController.forward();
},
onTap: () {
context.read<PetFeedingBloc>().add(SaturationSmallIncrementEvent());
_animationController.forward();
},
),
),
)
);
})
);
}
}
我认为你必须调用你的 emit 方法
PetFeedingBloc
class PetFeedingBloc extends Bloc<SaturationEvent, SaturationState> {
PetFeedingBloc()
: super(const SaturationState(saturationCount: 40.0)) {
on<SaturationSmallIncrementEvent>((event, emit) => emit(SaturationState(saturationCount: state.saturationCount + 15.0)) );
...
}
}
我正在使用 Flutter 编写一个小型电子鸡应用,现在我正在学习如何使用 flutter_bloc 库。 当用户点击屏幕上的宠物图像时,它必须重新绘制 CircularPercentIndicator 小部件,但它不会起作用。我正在尝试使用 BlocBuilder 和 BlocProvider classes 将视图与 bloc 连接起来,但它没有帮助。 点击宠物widget后,动画被转发,但是saturationCount和CircularPercentIndicator的状态还没有更新。
这是我的宠物喂养 BLoC:
class PetFeedingBloc extends Bloc<SaturationEvent, SaturationState> {
PetFeedingBloc()
: super(const SaturationState(saturationCount: 40.0)) {
on<SaturationSmallIncrementEvent>((event, emit) => state.saturationCount + 15.0);
on<SaturationBigIncrementEvent>((event, emit) => state.saturationCount + 55.0);
on<SaturationDecrementEvent>((event, emit) => state.saturationCount - 2.0);
}
}
在 SaturationBarWidget 中 class 我正在尝试将小部件中的百分比指示器与 BLoC 连接,但它不起作用。这是:
class SaturationBarWidget extends StatefulWidget {
const SaturationBarWidget({Key? key}) : super(key: key);
@override
State<SaturationBarWidget> createState() => SaturationBarWidgetState();
}
class SaturationBarWidgetState extends State<SaturationBarWidget> {
@override
void initState() {
Timer? timer;
timer = Timer.periodic(const Duration(milliseconds: 3000), (_) {
setState(() {
context.read<PetFeedingBloc>().add(SaturationDecrementEvent());
if (context.read<PetFeedingBloc>().state.saturationCount <= 0) {
timer?.cancel();
}
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return BlocBuilder<PetFeedingBloc, SaturationState>(builder: (context, state){
return CircularPercentIndicator(
radius: 50.0,
lineWidth: 20.0,
animateFromLastPercent: true,
percent: context.read<PetFeedingBloc>().state.saturationCount / 100,
center: const Icon(
Icons.emoji_emotions_outlined,
size: 50.0,
),
backgroundColor: Colors.blueGrey,
progressColor: Colors.blue,
);
});
}
}
这里是我的 PetWidget class,需要点击图片:
class PetWidget extends StatefulWidget {
const PetWidget({Key? key}) : super(key: key);
@override
State<PetWidget> createState() => PetWidgetState();
}
class PetWidgetState extends State<PetWidget> with TickerProviderStateMixin {
late Animation<Offset> _animation;
late AnimationController _animationController;
static GlobalKey<SaturationBarWidgetState> key = GlobalKey();
bool reverse = true;
Image cat = Image.asset('images/cat.png');
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 4));
_animation = Tween<Offset>(begin: Offset.zero, end: const Offset(1, 0))
.animate(CurvedAnimation(
parent: _animationController, curve: Curves.elasticIn));
_animationController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animationController.reverse();
}
});
//_animationController.forward();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(child:
BlocBuilder<PetFeedingBloc, SaturationState>(builder: (context, state) {
return Center(
child: SizedBox(
width: 300,
height: 400,
child: SlideTransition(
position: _animation,
child: GestureDetector(
child: cat,
onDoubleTap: () {
context.read<PetFeedingBloc>().add(SaturationBigIncrementEvent());
_animationController.forward();
},
onTap: () {
context.read<PetFeedingBloc>().add(SaturationSmallIncrementEvent());
_animationController.forward();
},
),
),
)
);
})
);
}
}
我认为你必须调用你的 emit 方法 PetFeedingBloc
class PetFeedingBloc extends Bloc<SaturationEvent, SaturationState> {
PetFeedingBloc()
: super(const SaturationState(saturationCount: 40.0)) {
on<SaturationSmallIncrementEvent>((event, emit) => emit(SaturationState(saturationCount: state.saturationCount + 15.0)) );
...
}
}