flutter_bloc 使用 flutter bloc 的库递增递减按钮
flutter_bloc library increment decrement button using flutter bloc
我是 flutter_bloc 库的新手,我正在尝试制作增量减量按钮的组件,但是当我尝试复制该组件时,我遇到了问题,当我按下第二个增量按钮时组件 第一个组件也像这样更新 result。我希望他们有不同的结果。我该如何解决?
这是我的集团代码:
import 'package:bloc/bloc.dart';
abstract class QtyEvent{}
class Increment extends QtyEvent {}
class Decrement extends QtyEvent {}
class QtyBloc extends Bloc<QtyEvent, int> {
QtyBloc() : super(0) {
on<Increment>((event, emit) =>
emit(state+1));
on<Decrement>((event, emit) =>
emit(state-1));
}
}
这是我的组件代码:
class _QtyState extends State<Qty> {
int _n = 0;
@override
void add() {
setState(() {
_n++;
});
context.read<QtyBloc>().add(Increment());
}
void minus() {
setState(() {
if (_n != 0) _n--;
});
context.read<QtyBloc>().add(Decrement());
}
QtyBloc qtybloc = QtyBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),),
body: Column(
children: [
Row(
children: [
GestureDetector(
onTap: minus,
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: Icon(Icons.remove),
),
),
Text(
context.watch<QtyBloc>().state.toString(),
style: TextStyle(fontSize: 20),
),
GestureDetector(
onTap: add,
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: Icon(Icons.add),
),
),
],
),
],
),
);
}
}
您的代码完全按照设计的目的运行。
如果我理解正确的话,你想使用同一个 Bloc 来拥有两个 sets of increment
& decrement
buttons?
因为你是emitting
单身state
,当你在一个地方更新它时,它会到处更新!
此外,您不需要调用 setState
,因为它会重新呈现 UI,这可以通过 bloc it self 实现。
并且,在您提到的标题中您使用 flutter_bloc
,但在您的代码中,您使用的是 bloc
。
这里是如何用 flutter_bloc
,
实现它
logic.dart
import 'package:flutter_bloc/flutter_bloc.dart';
class CounterEvent {
const CounterEvent();
}
class Increment extends CounterEvent {
final int value1, value2;
const Increment({this.value1 = 1, this.value2 = 1});
}
class Decrement extends CounterEvent {
final int value1, value2;
const Decrement({this.value1 = 1, this.value2 = 1});
}
class Reset extends CounterEvent {
final int value;
const Reset({this.value = 0});
}
class CounterState {
final int s1, s2; // Just maintain 2 values!
const CounterState({required this.s1, required this.s2});
}
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc(CounterState initialState) : super(initialState);
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
if (event is Increment) {
yield CounterState(
s1: state.s1 + event.value1, s2: state.s2 + event.value2);
} else if (event is Decrement) {
yield CounterState(
s1: state.s1 - event.value1, s2: state.s2 - event.value2);
} else if (event is Reset) {
yield CounterState(s1: event.value, s2: event.value);
}
}
}
component_page.dart
class Component extends StatelessWidget {
const Component({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Counter'),
),
body: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Column(
children: [
Row(
children: [
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Decrement(value1: 1, value2: 0));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.remove),
),
),
Text(
state.s1.toString(),
style: const TextStyle(fontSize: 20, color: Colors.white),
),
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Increment(value1: 1, value2: 0));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.add),
),
),
],
),
Row(
children: [
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Decrement(value1: 0, value2: 1));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.remove),
),
),
Text(
state.s2.toString(),
style: const TextStyle(fontSize: 20, color: Colors.white),
),
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Increment(value1: 0, value2: 1));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.add),
),
),
],
),
Row(
children: [
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Reset(value: 0));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.refresh),
),
),
],
),
],
);
},
),
);
}
}
备注
- 此代码是用空安全编写的
- 记得在您的应用周围添加
BlocProvider
,如下所示:
main.dart
void main() async {
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider<CounterBloc>(
create: (_) => CounterBloc(const CounterState(s1: 0, s2: 0)),
child: const MaterialApp(
debugShowCheckedModeBanner: false,
home: Component(),
),
);
}
}
我是 flutter_bloc 库的新手,我正在尝试制作增量减量按钮的组件,但是当我尝试复制该组件时,我遇到了问题,当我按下第二个增量按钮时组件 第一个组件也像这样更新 result。我希望他们有不同的结果。我该如何解决?
这是我的集团代码:
import 'package:bloc/bloc.dart';
abstract class QtyEvent{}
class Increment extends QtyEvent {}
class Decrement extends QtyEvent {}
class QtyBloc extends Bloc<QtyEvent, int> {
QtyBloc() : super(0) {
on<Increment>((event, emit) =>
emit(state+1));
on<Decrement>((event, emit) =>
emit(state-1));
}
}
这是我的组件代码:
class _QtyState extends State<Qty> {
int _n = 0;
@override
void add() {
setState(() {
_n++;
});
context.read<QtyBloc>().add(Increment());
}
void minus() {
setState(() {
if (_n != 0) _n--;
});
context.read<QtyBloc>().add(Decrement());
}
QtyBloc qtybloc = QtyBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),),
body: Column(
children: [
Row(
children: [
GestureDetector(
onTap: minus,
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: Icon(Icons.remove),
),
),
Text(
context.watch<QtyBloc>().state.toString(),
style: TextStyle(fontSize: 20),
),
GestureDetector(
onTap: add,
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: Icon(Icons.add),
),
),
],
),
],
),
);
}
}
您的代码完全按照设计的目的运行。
如果我理解正确的话,你想使用同一个 Bloc 来拥有两个 sets of increment
& decrement
buttons?
因为你是emitting
单身state
,当你在一个地方更新它时,它会到处更新!
此外,您不需要调用 setState
,因为它会重新呈现 UI,这可以通过 bloc it self 实现。
并且,在您提到的标题中您使用 flutter_bloc
,但在您的代码中,您使用的是 bloc
。
这里是如何用 flutter_bloc
,
logic.dart
import 'package:flutter_bloc/flutter_bloc.dart';
class CounterEvent {
const CounterEvent();
}
class Increment extends CounterEvent {
final int value1, value2;
const Increment({this.value1 = 1, this.value2 = 1});
}
class Decrement extends CounterEvent {
final int value1, value2;
const Decrement({this.value1 = 1, this.value2 = 1});
}
class Reset extends CounterEvent {
final int value;
const Reset({this.value = 0});
}
class CounterState {
final int s1, s2; // Just maintain 2 values!
const CounterState({required this.s1, required this.s2});
}
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc(CounterState initialState) : super(initialState);
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
if (event is Increment) {
yield CounterState(
s1: state.s1 + event.value1, s2: state.s2 + event.value2);
} else if (event is Decrement) {
yield CounterState(
s1: state.s1 - event.value1, s2: state.s2 - event.value2);
} else if (event is Reset) {
yield CounterState(s1: event.value, s2: event.value);
}
}
}
component_page.dart
class Component extends StatelessWidget {
const Component({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Counter'),
),
body: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Column(
children: [
Row(
children: [
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Decrement(value1: 1, value2: 0));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.remove),
),
),
Text(
state.s1.toString(),
style: const TextStyle(fontSize: 20, color: Colors.white),
),
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Increment(value1: 1, value2: 0));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.add),
),
),
],
),
Row(
children: [
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Decrement(value1: 0, value2: 1));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.remove),
),
),
Text(
state.s2.toString(),
style: const TextStyle(fontSize: 20, color: Colors.white),
),
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Increment(value1: 0, value2: 1));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.add),
),
),
],
),
Row(
children: [
GestureDetector(
onTap: () {
BlocProvider.of<CounterBloc>(context)
.add(const Reset(value: 0));
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red),
child: const Icon(Icons.refresh),
),
),
],
),
],
);
},
),
);
}
}
备注
- 此代码是用空安全编写的
- 记得在您的应用周围添加
BlocProvider
,如下所示:
main.dart
void main() async {
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider<CounterBloc>(
create: (_) => CounterBloc(const CounterState(s1: 0, s2: 0)),
child: const MaterialApp(
debugShowCheckedModeBanner: false,
home: Component(),
),
);
}
}