【发布时间】:2021-08-13 03:50:45
【问题描述】:
我在“MyButton”小部件中使用BlocConsumer,该小部件用于列表中的所有项目。 当用户按下按钮时,我想根据用户单击的按钮将用户重定向到另一个页面(在下面的代码中,将打印按钮文本)。
如果我运行此代码,单击按钮会打印所有文本(“Press 1”、“Press 2”、“Press 3”)。 是因为完全相同的侦听器附加到 MyButton 小部件 3 次,并且每当单击任何按钮时都会调用所有侦听器? 这是否意味着同一页面上的一个块不应有多个小部件?
我可以通过移动 BlocConsumer 来包装 Column 而不是 MyButton 来修复代码。这是处理这个问题的正确方法吗?如果是这种情况,我必须在更复杂的情况下包装一个更大的小部件。例如,如果 appbar 和 body 中的小部件使用相同的 bloc,那么我将不得不用 BlocConsumer 包装整个页面。
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() async {
runApp(BlocProvider<MyBloc>(
create: (BuildContext context) => MyBloc(),
child: MaterialApp(
home: Column(
children: [
MyButton(text: "Press 1"),
MyButton(text: "Press 2"),
MyButton(text: "Press 3"),
],
),
),
));
}
class MyButton extends StatelessWidget {
const MyButton({Key? key, required this.text}) : super(key: key);
final String text;
@override
Widget build(BuildContext context) {
return BlocConsumer<MyBloc, MyState>(
listenWhen: (previous, current) {
return true;
},
listener: (context, state) {
print(text);
},
builder: (context, state) {
return TextButton(
key: UniqueKey(),
child: Text(text),
onPressed: () {
context.read<MyBloc>().add(MyEvent());
},
);
},
);
}
}
class MyEvent {}
class MyState {}
class MyBloc extends Bloc<MyEvent, MyState> {
MyBloc() : super(MyState());
@override
Stream<MyState> mapEventToState(MyEvent event) async* {
yield MyState();
}
}
【问题讨论】: