-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BLoC 架构 #24
Comments
Business Logic Component
设计规范
UI 设计规范
|
用流重写计数器的例子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.
);
}
} |
用BLoC重写计数器的例子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组件来释放资源。 |
增加BlocProviderimport '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;
}
}
|
引入rxdartimport '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;
}
}
|
引入 flutter_blocimport '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;
}
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No description provided.
The text was updated successfully, but these errors were encountered: