Flutter learning (a) state management

There in the flutter of a new concept: BLOC
It is a method for constructing applications using reactive programming mode, which is a by the stream composed of fully asynchronous world. First explain what is the flow

flow:

That is Stream, a pipeline is a real-life example with two ends, only one allowed to insert some things. When something you inserted into the pipe, it flows within the pipe and out the other end.
In fact, it is designed to handle asynchronous events and students.
Here Insert Picture Description

  • The big machine is StreamController, it is one way to create a stream.
  • StreamController have an entry called sink
  • sink can use the add method to put things in, go into the future is no longer a concern.
  • When there is something from the future sink in, our machine will start to work it, empty space.
  • StreamController there is an exit is called stream
  • Finished products after processing machine will throw out from the exit, but we do not know when it will come out, so we need to listen to listen to this method has been exported.
  • And when a plurality of articles to be placed, and it will not be out of sequence, but the FIFO.

Like the observer pattern, there is a listener has been listening for export, once there is a change of data out of it to make business change. Vue lot like two-way data binding.

BLoC:

A method of constructing BLoC is applied using a reactive programming mode, which is composed of a totally asynchronous stream world.
Here Insert Picture Description

  • Stateful member wrapped by StreamBuilder, streambuilder a stream will listen
  • The flow from BLoC
  • Status data from the widget to monitor flow.
  • User interaction gesture is detected, an event is generated. For example, pressed the button.
  • Calls bloc's capabilities to handle this event
  • After completion of the processing in the bloc will add new data into the stream sink in
  • StreamBuilder listening to the new data, generate a new snapshot, and re-build method calls
  • Widget is reconstructed

achieve

The following examples are actually https://www.jianshu.com/p/7573dee97dbb example, simply want to record what
Here Insert Picture Description

1. main.dart:

import 'package:flutter/material.dart';
import 'package:flutter_bloctest/BlocProvider.dart';
import 'package:flutter_bloctest/TopPage.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget{  //statelessWidget是没有状态的控件,与statefulWidget相对
  @override
  Widget build(BuildContext context) {
    return BlocProvider(  //BlocProvider是自己写的代码
      child: MaterialApp( //继承自StatefulWidget,一个封装了很多所必须要的组件的小部件,一般作为顶层widget使用
        title: 'scoped',
        theme: ThemeData.dark(),
        home: TopPage(),  //一般在MaterialApp的home我们会放一个Scaffold,可以看到TopPage就是return一个Scaffold的
      ),
    );
  }
}
  1. CountBLoC.dart:
import 'dart:async';

import 'package:flutter/material.dart';

//创建一个bloc
class CountBLoC {
  int _count;
  StreamController<int> _countController;

  CountBLoC() {
    _count = 0;

    /*注册一个int类型的StreamController
    这里broadcast是因为一个单订阅流不能有多个收听者,
    我们的app中有2个页面都需要监听这个数据,所以需要将其转为广播流。
    “广播流允许任意数量的收听者,且无论是否有收听者,他都能产生事件。
    所以中途进来的收听者将不会收到之前的消息。”
     */
    _countController = StreamController<int>.broadcast();
  }

  Stream<int> get stream => _countController.stream;  //暴露出流
  int get value => _count;  //暴露出value

  increment() {
    _countController.sink.add(++_count);  //把新数据add进流的sink中
  }

  dispose() {
    _countController.close(); //关闭流
  }
}
  1. BlocProvider.dart:
 import 'package:flutter/material.dart';

import 'CountBLoC.dart';

/*
InheritedWidget是Flutter的一个功能型的Widget基类,
它能有效地将数据在当前Widget树中向它的子widget树传递。
 */
class BlocProvider extends InheritedWidget {
  @override
  CountBLoC bloc = CountBLoC();

  BlocProvider({Key key, Widget child}) : super(key: key, child: child);

//用于控制刷新时机
  @override
  bool updateShouldNotify(InheritedWidget oldWidget) {
    // TODO: implement updateShouldNotify
    return false;
  }

  /*of方法,用于获取到bloc
  它的子Widget树可以通过 BuildContext.inheritedFromWidgetOfExactType()方法获得最近的指定类型的Inherited widget,
  进而获取它的共享数据
   */
  static CountBLoC of(BuildContext context) =>
      (context.inheritFromWidgetOfExactType(BlocProvider) as BlocProvider).bloc;

}

4. TopPage.dart:

 import 'package:flutter/material.dart';
import 'package:flutter_bloctest/BlocProvider.dart';
import 'package:flutter_bloctest/UnderPage.dart';

class TopPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    final bloc = BlocProvider.of(context);  //检索bloc
    return Scaffold(
      appBar: AppBar(
        title: Text('Top Page'),
      ),
      body: Center(
        /*
        StreamBuilder其实是一个StatefulWidget,它通过监听stream,发现有数据输出时,
        自动重建,调用builder方法
         */
        child: StreamBuilder<int>(
            stream: bloc.stream,
            initialData: bloc.value,//获取初始化的值
            builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
              return Text(
                'You hit me:${snapshot.data} times',  //取出data
                style: Theme.of(context).textTheme.display1,  //小字体,display2是中字体...
              );
            }),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.navigate_next),
        //跳到下个页面
        onPressed: ()=>Navigator.of(context).push(MaterialPageRoute(builder: (context)=>UnderPage())),
      ),
    );
  }
}

5. UnderPage:

import 'package:flutter/material.dart';
import 'package:flutter_bloctest/BlocProvider.dart';


class UnderPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final bloc = BlocProvider.of(context);
    print("build");
    return Scaffold(
      appBar: AppBar(
        title: Text('Under Page'),
      ),
      body: Center(
        child: StreamBuilder<int>(
            stream: bloc.stream,
            initialData: bloc.value,
            builder: (BuildContext context, AsyncSnapshot<int> snapshot) => Text(
                  "You hit me : ${snapshot.data} times",
                  style: Theme.of(context).textTheme.display1,
                )),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => bloc.increment(),  //调用添加value的那个函数
        child: Icon(Icons.add),
      ),
    );
  }
}

附上github:https://github.com/aopo1104/flutterLearn

References:

https://element.eleme.cn/#/zh-CN/component/icon
https://www.jianshu.com/p/7573dee97dbb
https://www.jianshu.com/p/346dc2a8cbde

Published 57 original articles · won praise 3 · Views 6190

Guess you like

Origin blog.csdn.net/qq_39830579/article/details/103643888