在Flutter中使用流/接收器 [英] Using Stream/Sink in Flutter
问题描述
我正在尝试使用
I'm trying to replace the increment
flutter app code, by using Streams from Dart API without using scoped_model or rxdart.
So I read this and watched this, but could not get it work for me, my codes are:
StreamProvider.dart
:
import 'package:flutter/widgets.dart';
import 'businessLogic.dart';
import 'dart:async';
class Something {
final _additionalContrllerr = StreamController<int>();
Sink<int> get addition => _additionalContrllerr.sink;
Stream<int> get itemCount => _additionalContrllerr.stream;
}
class StreemProvider extends InheritedWidget {
final Something myBloc; // Business Logic Component
StreemProvider({
Key key,
@required this.myBloc,
Widget child,
}) : super(key: key, child: child);
@override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
static Something of(BuildContext context) =>
(context.inheritFromWidgetOfExactType(StreemProvider) as StreemProvider)
.myBloc;
}
main.dart
:
import 'package:flutter/material.dart';
import 'package:flutter_app/StreemProvider.dart';
void main() => runApp(MyApp(
textInput: Text("Provided By the Main"),
));
class MyApp extends StatefulWidget {
final Widget textInput;
MyApp({this.textInput});
@override
State<StatefulWidget> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
bool checkBoxValue = false;
int _counter = 0;
@override
Widget build(BuildContext ctxt) {
var x = Something(); //// Not sure if have to use this!
return StreemProvider(
myBloc: x, //// Not sure about this!!
child: MaterialApp(
home: SafeArea(
child: Scaffold(
body: new Center(
child: new Column(
children: <Widget>[
widget.textInput,
Text("clickec $_counter times"),
Text("clickec ${x.itemCount.listen((int i) => i)} times"),
/// How to get the value of i??!
Checkbox(
value: checkBoxValue,
onChanged: (bool newValue){
setState(() {
checkBoxValue = newValue;
});
}
)
],
)),
floatingActionButton: Incrementer(_increment),
// floatingActionButton: Incrementer(x),
),
),
),
);
}
_increment() {
setState(() {
_counter += 1;
});
}
}
class Incrementer extends StatefulWidget {
final Function increment;
Incrementer(this.increment);
@override
State<StatefulWidget> createState() {
return IncrementerState();
}
}
class IncrementerState extends State<Incrementer>{
@override
Widget build(BuildContext ctxt) {
final myBloc = StreemProvider.of(context);
return new FloatingActionButton(
//onPressed: widget.increment,
// How ot get the latest value!!
onPressed: () async {
var y = await myBloc.itemCount.last;
if (y.isNaN) y = 0;
myBloc.addition.add(y+1);
},
child: new Icon(Icons.add),
);
}
}
推荐答案
感谢 vbandrade 很多,他的回答帮助我弄清楚了。与我一起工作的解决方案是:
Thanks a lot to vbandrade his answer helped me figuring t out. the solution worked with me is:
如果我需要听一个<$,我需要2个 StreamController
c $ c>接收器在我的 bloc
业务逻辑组件中,然后处理并
I need to have 2 StreamController
if I need to listen to a sink
in my bloc
Business Logic Component, then process and stream
the output to other elements.
counter_bloc.dart
是:
import 'dart:async';
class CounterBloc {
int _count = 0;
// The controller to stream the final output to the required StreamBuilder
final _counter = StreamController.broadcast<int>();
Stream<int> get counter => _counter.stream;
// The controller to receive the input form the app elements
final _query = StreamController<int>();
Sink<int> get query => _query.sink;
Stream<int> get result => _query.stream;
// The business logic
CounterBloc() {
result.listen((increment) { // Listen for incoming input
_count += increment; // Process the required data
_counter.add(_count); // Stream the required output
});
}
void dispose(){
_query.close();
_counter.close();
}
}
和 main.dart
是:
import 'counter_bloc.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
State<StatefulWidget> createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
var bloc = CounterBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder<int>( // Listen to the final output sent from the Bloc
stream: bloc.counter,
initialData: 0,
builder: (BuildContext c, AsyncSnapshot<int> data) {
return Text(
'${data.data}',
style: Theme.of(context).textTheme.display1,
);
},
),
],
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
onPressed: () {
bloc.query.add(2); // Send input to the Bloc
},
tooltip: 'Increment 2',
child: Text("+2"),
),
FloatingActionButton(
onPressed: () {
bloc.query.add(1); // Send input to the Bloc
},
tooltip: 'Increment 1',
child: Text("+1"),
),
],
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
这篇关于在Flutter中使用流/接收器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!