Open OPY-bbt opened 4 years ago
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@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
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
StreamController _ctrl = StreamController<int>();
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_ctrl.close();
}
@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>(
stream: _ctrl.stream,
initialData: _counter,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.display1,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_ctrl.sink.add(++_counter);
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@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 StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
final IncrementBloc bloc = IncrementBloc();
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder<int>(
stream: bloc.ctrl.stream,
initialData: bloc.counter,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.display1,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: bloc.add,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class IncrementBloc {
int counter = 0;
StreamController ctrl = StreamController<int>();
@override
void dispose() {
ctrl.close();
}
add() {
ctrl.sink.add(++counter);
}
}
但是虽然组件都变成了statelessWidget。dispose应该放在哪里呢?所以还是需要一个statefulWidget组件来释放资源。
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BlocProvider(
bloc: IncrementBloc(),
child: MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
final IncrementBloc bloc = BlocProvider.of<IncrementBloc>(context);
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder<int>(
stream: bloc.ctrl.stream,
initialData: bloc.counter,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.display1,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: bloc.add,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
//所有BLoC的通用接口
abstract class BlocBase {
void dispose();
}
class IncrementBloc implements BlocBase {
int counter = 0;
StreamController ctrl = StreamController<int>();
@override
void dispose() {
ctrl.close();
}
add() {
ctrl.sink.add(++counter);
}
}
//通用BLoC提供商
class BlocProvider<T extends BlocBase> extends StatefulWidget {
BlocProvider({
Key key,
@required this.child,
@required this.bloc,
}) : super(key: key);
final T bloc;
final Widget child;
static T of<T extends BlocBase>(BuildContext context) {
var type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
return provider.bloc;
}
static Type _typeOf<T>() => T;
@override
_BlocProviderState createState() {
// TODO: implement createState
return _BlocProviderState();
}
}
class _BlocProviderState<T> extends State<BlocProvider<BlocBase>> {
@override
void dispose() {
// TODO: implement dispose
widget.bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return widget.child;
}
}
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BlocProvider(
bloc: IncrementBloc(),
child: MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
final IncrementBloc bloc = BlocProvider.of<IncrementBloc>(context);
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder<int>(
stream: bloc.stream,
initialData: bloc.counter,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.display1,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: bloc.add,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
//所有BLoC的通用接口
abstract class BlocBase {
void dispose();
}
class IncrementBloc implements BlocBase {
int counter = 0;
BehaviorSubject<int> _controller = BehaviorSubject<int>();
Stream<int> get stream => _controller.stream;
@override
void dispose() {
_controller.close();
}
add() {
_controller.sink.add(++counter);
}
}
//通用BLoC提供商
class BlocProvider<T extends BlocBase> extends StatefulWidget {
BlocProvider({
Key key,
@required this.child,
@required this.bloc,
}) : super(key: key);
final T bloc;
final Widget child;
static T of<T extends BlocBase>(BuildContext context) {
var type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
return provider.bloc;
}
static Type _typeOf<T>() => T;
@override
_BlocProviderState createState() {
// TODO: implement createState
return _BlocProviderState();
}
}
class _BlocProviderState<T> extends State<BlocProvider<BlocBase>> {
@override
void dispose() {
// TODO: implement dispose
widget.bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return widget.child;
}
}
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BlocProvider(
create: (BuildContext context) => IncrementBloc(),
child: MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
final IncrementBloc bloc = BlocProvider.of<IncrementBloc>(context);
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
BlocBuilder<IncrementBloc, int>(
builder: (BuildContext context, counter) {
return Text(
'$counter',
style: Theme.of(context).textTheme.display1,
);
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
bloc.add(CounterEvent.add);
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
enum CounterEvent { add }
class IncrementBloc extends Bloc<CounterEvent, int> {
@override
int get initialState => 0;
@override
Stream<int> mapEventToState(CounterEvent event) async* {
switch (event) {
case CounterEvent.add:
yield state + 1;
break;
}
}
}
Business Logic Component
事实上,BLoC模式最初被设想为允许独立于平台重用相同的代码
youtube设计规范
UI 设计规范