一尘不染

在Flutter中使用流/接收器

flutter

我正在尝试increment通过使用Dart
API中的而不使用scoped_modelrxdart来替换flutter应用程序代码。

所以,看着这个,但不能让它为我工作,我的代码如下:

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),
        );
    }
  }

阅读 336

收藏
2020-08-13

共1个答案

一尘不染

非常感谢vbandrade,他的回答帮助我弄清楚了。与我合作的解决方案是:

StreamController如果需要sink在我的bloc业务逻辑组件中侦听a ,然后stream将其输出到其他元素,则需要2 。

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.
    );
  }
}
2020-08-13