我正在使用 BLOC 制作一个简单的计数器应用程序,但是当我递增/递减时我的计数器没有更新?我使用 BlocBuilder 构建 UI
I am using BLOC to make a simple counter app , but my counter is not updating when I am incrementing / decrementing it? I used BlocBuilder to build UI
我已将 MaterialApp 包装在 BlocProvider 下,并且我还使用 BlocBuilder 构建 UI(反文字)
我有两个浮动操作按钮,每个按钮分别调用 Incrementevent() 和 Decrementevent(),但 UI 仍然没有改变。
请提出解决方案。
我的 main.dart 文件
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CounterBloc(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _counterBloc = CounterBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${state.counter}',
style: Theme.of(context).textTheme.headline4,
),
],
),
);
},
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => _counterBloc.add(Incrementevent()),
tooltip: 'Decrement',
child: Icon(Icons.remove),
),
SizedBox(width: 10),
FloatingActionButton(
onPressed: () => _counterBloc.add(Decrementevent()),
tooltip: 'Increment',
child: Icon(Icons.add),
),
],
),
);
}
@override
void dispose() {
// TODO: implement dispose
_counterBloc.close();
super.dispose();
}
}
我的 counter_event 文件
part of 'counter_bloc.dart';
@immutable
abstract class CounterEvent {}
class Incrementevent extends CounterEvent {}
class Decrementevent extends CounterEvent {}
我的 counter_state 文件
part of 'counter_bloc.dart';
@immutable
abstract class CounterState {
final int counter;
const CounterState(this.counter);
}
class CounterInitial extends CounterState {
CounterInitial(int counter) : super(counter);
}
我的 counter_bloc 文件
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
part 'counter_event.dart';
part 'counter_state.dart';
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterInitial(0));
@override
Stream<CounterState> mapEventToState(
CounterEvent event,
) async* {
if (event is Incrementevent) {
yield CounterInitial(state.counter + 1);
} else if (event is Decrementevent) {
yield CounterInitial(state.counter - 1);
}
}
}
TL;DR 您正在创建同一个 BLoC 的两个实例,因此通过在一个 BLoC 上触发事件,另一个不会得到更新。
在 MyApp
小部件中,您创建一个 BLoC 实例并使用 BlocProvider
将其提供给小部件树 - 这里的一切都很完美。
但是,在 _MyHomePageState
中,您正在创建同一 CounterBloc
的另一个实例并使用它来添加事件。这意味着,您在与之前提供的不同的 BLoC 上运行。
要解决此问题,您应该获取注入的 BLoC 实例并对其进行操作。由于 BLoC 库依赖于 provider
,您可以像这样解析注入的 BLoC:
@override
Widget build(BuildContext context) {
final counterBloc = context.watch<CounterBloc>();
...
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => counterBloc.add(Incrementevent()),
tooltip: 'Decrement',
child: Icon(Icons.remove),
),
SizedBox(width: 10),
FloatingActionButton(
onPressed: () => counterBloc.add(Decrementevent()),
tooltip: 'Increment',
child: Icon(Icons.add),
),
],
),
...
}
或者这样:
@override
Widget build(BuildContext context) {
...
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => context.read<CounterBloc>().add(Incrementevent()),
tooltip: 'Decrement',
child: Icon(Icons.remove),
),
SizedBox(width: 10),
FloatingActionButton(
onPressed: () => context.read<CounterBloc>().add(Decrementevent()),
tooltip: 'Increment',
child: Icon(Icons.add),
),
],
),
...
}
我已将 MaterialApp 包装在 BlocProvider 下,并且我还使用 BlocBuilder 构建 UI(反文字) 我有两个浮动操作按钮,每个按钮分别调用 Incrementevent() 和 Decrementevent(),但 UI 仍然没有改变。 请提出解决方案。
我的 main.dart 文件
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CounterBloc(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _counterBloc = CounterBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${state.counter}',
style: Theme.of(context).textTheme.headline4,
),
],
),
);
},
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => _counterBloc.add(Incrementevent()),
tooltip: 'Decrement',
child: Icon(Icons.remove),
),
SizedBox(width: 10),
FloatingActionButton(
onPressed: () => _counterBloc.add(Decrementevent()),
tooltip: 'Increment',
child: Icon(Icons.add),
),
],
),
);
}
@override
void dispose() {
// TODO: implement dispose
_counterBloc.close();
super.dispose();
}
}
我的 counter_event 文件
part of 'counter_bloc.dart';
@immutable
abstract class CounterEvent {}
class Incrementevent extends CounterEvent {}
class Decrementevent extends CounterEvent {}
我的 counter_state 文件
part of 'counter_bloc.dart';
@immutable
abstract class CounterState {
final int counter;
const CounterState(this.counter);
}
class CounterInitial extends CounterState {
CounterInitial(int counter) : super(counter);
}
我的 counter_bloc 文件
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
part 'counter_event.dart';
part 'counter_state.dart';
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterInitial(0));
@override
Stream<CounterState> mapEventToState(
CounterEvent event,
) async* {
if (event is Incrementevent) {
yield CounterInitial(state.counter + 1);
} else if (event is Decrementevent) {
yield CounterInitial(state.counter - 1);
}
}
}
TL;DR 您正在创建同一个 BLoC 的两个实例,因此通过在一个 BLoC 上触发事件,另一个不会得到更新。
在 MyApp
小部件中,您创建一个 BLoC 实例并使用 BlocProvider
将其提供给小部件树 - 这里的一切都很完美。
但是,在 _MyHomePageState
中,您正在创建同一 CounterBloc
的另一个实例并使用它来添加事件。这意味着,您在与之前提供的不同的 BLoC 上运行。
要解决此问题,您应该获取注入的 BLoC 实例并对其进行操作。由于 BLoC 库依赖于 provider
,您可以像这样解析注入的 BLoC:
@override
Widget build(BuildContext context) {
final counterBloc = context.watch<CounterBloc>();
...
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => counterBloc.add(Incrementevent()),
tooltip: 'Decrement',
child: Icon(Icons.remove),
),
SizedBox(width: 10),
FloatingActionButton(
onPressed: () => counterBloc.add(Decrementevent()),
tooltip: 'Increment',
child: Icon(Icons.add),
),
],
),
...
}
或者这样:
@override
Widget build(BuildContext context) {
...
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => context.read<CounterBloc>().add(Incrementevent()),
tooltip: 'Decrement',
child: Icon(Icons.remove),
),
SizedBox(width: 10),
FloatingActionButton(
onPressed: () => context.read<CounterBloc>().add(Decrementevent()),
tooltip: 'Increment',
child: Icon(Icons.add),
),
],
),
...
}