从多个小部件访问 StreamController Stream
Posted
技术标签:
【中文标题】从多个小部件访问 StreamController Stream【英文标题】:Access StreamController Stream from multiple widgets 【发布时间】:2020-10-25 04:13:50 【问题描述】:您好,我是 Flutter 和 Streams、BLoC 和提供程序的新手。
我正在尝试从两个不同的小部件访问流。虽然它适用于一个小部件,但它不适用于另一个小部件。我在两个小部件中都有单独的流构建器,我认为这可能是问题所在。为什么它不起作用?我做错了什么而不理解?
带有流控制器和流的 BloC:
String dialCode = "";
class LogInController
final dialCodeStreamController = StreamController<String>();
Stream<String> get dialCodeStream => dialCodeStreamController.stream;
final dialCodeUpdateStreamController = StreamController<String>();
Sink<String> get dialCodeSink => dialCodeUpdateStreamController.sink;
Stream<String> get dialCodeUpdateStream =>
dialCodeUpdateStreamController.stream;
LogInController()
dialCodeUpdateStream.listen((updatedDialCode)
dialCode = updatedDialCode;
dialCodeStreamController.add(dialCode);
);
void dispose()
dialCodeStreamController.close();
dialCodeUpdateStreamController.close();
流工作的小部件:
class CountryCodeWidget extends StatelessWidget
final LogInController controller = LogInController();
@override
Widget build(BuildContext context)
return Container(
margin: const EdgeInsets.fromLTRB(12, 12, 12, 8),
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
selectCountryCodeString,
style: hintTextStyle,
),
StreamBuilder<String>(
stream: controller.dialCodeStream,
initialData: "",
builder: (context, snapshot)
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: snapshot.data == ""
? whiteColor
: secondaryColor,
width: 4,
),
),
),
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
'$snapshot.data',
style: textStyle,
),
),
);
),
FlatButton(
color: secondaryColor,
child: Icon(
Icons.keyboard_arrow_down,
color: textColor,
),
onPressed: () => countryCodeDialog(context),
),
],
),
),
),
);
流不工作的小部件:
class MobileNumberWidget extends StatelessWidget
final LogInController controller = LogInController();
final mobileNumberController = TextEditingController();
@override
Widget build(BuildContext context)
return Container(
margin: const EdgeInsets.fromLTRB(12, 0, 12, 8),
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: TextField(
controller: mobileNumberController,
keyboardType: TextInputType.phone,
style: textStyle,
decoration: InputDecoration(
hintText: mobileNumberHintString,
hintStyle: hintTextStyle,
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: hintTextColor,
width: 1,
),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: textColor,
width: 2,
),
),
),
),
),
),
StreamBuilder<String>(
stream: controller.dialCodeStream,
initialData: "",
builder: (context, snapshot)
return FlatButton(
child: Icon(
Icons.done,
color: textColor,
),
onPressed: () => mobileNumberController.text.length == 10
? snapshot.data == ""
? showSnackBar(
context, selectCountryCodeSnackBarString)
: //sendOTP(mobileNumberController.text)
showSnackBar(context, "YEs")
: showSnackBar(context, mobileNumberLengthString),
);
),
],
),
),
),
);
如果我能更好地解释我的问题,或者我是否没有意义,请告诉我。谢谢。
【问题讨论】:
是的,您已经创建了控制器的两个实例。我建议你使用flutter_bloc
库,它完全消除了处理所有这些的开销,而且你增加了代码的可读性。
我可以使用 flutter_bloc、scoped_model 或提供程序库,但我想自己尝试而不是依赖第三方库。我尝试广播流控制器,但它似乎不起作用。有很多解决方法,但我想尝试使这项工作。还是谢谢!
【参考方案1】:
找到问题和解决方案。两次初始化流控制器是问题所在。我在父小部件中初始化并将其传递给子小部件。
【讨论】:
你试过 StreamController.Broadcast 吗?创建一个可以被多个小部件监听的流以上是关于从多个小部件访问 StreamController Stream的主要内容,如果未能解决你的问题,请参考以下文章