flutter Bloc状态管理 改变主题等
2018-11-09 本文已影响1766人
麦芽的香气_c582
1.在构建APP的时候,需要考虑组件的状态,但是不通的组件,我们不可能一直传值传下去,在比较了Redux和Bloc模式后,果断选择了Bloc来管理app的状态
2.什么是BLOC? Bloc的原理可以看看这篇文章
https://www.jianshu.com/p/024b19dea138
3.本次demo使用的是flutter_bloc他是将bloc进一步封装,代码简化
import 'package:flutter/material.dart';
import 'package:bloc/bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:todo_redux_demo/theme_bloc.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
final CounterBloc _counterBloc = CounterBloc();
var themeBloc = ThemeBloc();
@override
Widget build(BuildContext context) {
return BlocProvider<ThemeBloc>(
bloc: themeBloc,
child: BlocBuilder(
bloc: themeBloc,
builder: (BuildContext context, bool state) {
return MaterialApp(
title: 'Flutter Demo',
theme: state == true ? lightTheme : darkTheme,
home: BlocProvider<CounterBloc>(
bloc: _counterBloc,
child: CounterPage(),
),
);
},
));
}
}
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final CounterBloc _counterBloc = BlocProvider.of<CounterBloc>(context);
final ThemeBloc themeBloc = BlocProvider.of<ThemeBloc>(context);
return Scaffold(
appBar: AppBar(title: Text('Counter')),
body: BlocBuilder<CounterEvent, int>(
bloc: _counterBloc,
builder: (BuildContext context, int count) {
return Center(
child: Text(
'$count',
style: TextStyle(fontSize: 24.0),
),
);
},
),
floatingActionButton: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 5.0),
child: FloatingActionButton(
child: Icon(Icons.add),
onPressed: _counterBloc.increment,
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 5.0),
child: FloatingActionButton(
child: Icon(Icons.remove),
onPressed: _counterBloc.decrement,
),
),
BlocBuilder<ThemeEvent, bool>(
bloc: themeBloc,
builder: (BuildContext context, bool) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 5.0),
child: FloatingActionButton(
child: Icon(Icons.insert_comment),
onPressed: () {
themeBloc.changeTheme();
},
),
);
},
)
],
),
);
}
}
abstract class CounterEvent {}
class IncrementCounter extends CounterEvent {
@override
String toString() => 'IncrementCounter';
}
class DecrementCounter extends CounterEvent {
@override
String toString() => 'DecrementCounter';
}
class CounterBloc extends Bloc<CounterEvent, int> {
void increment() {
dispatch(IncrementCounter());
}
void decrement() {
dispatch(DecrementCounter());
}
@override
int get initialState => 0;
@override
void onTransition(Transition<CounterEvent, int> transition) {
print(transition.toString());
}
@override
Stream<int> mapEventToState(int state, CounterEvent event) async* {
if (event is IncrementCounter) {
yield state + 1;
}
if (event is DecrementCounter) {
yield state - 1;
}
}
}
final ThemeData darkTheme = new ThemeData(
brightness: Brightness.dark,
buttonColor: Colors.blueAccent,
unselectedWidgetColor: Colors.white,
primaryTextTheme:
new TextTheme(caption: new TextStyle(color: Colors.white)));
final ThemeData lightTheme = new ThemeData(
primaryColor: Colors.blue,
backgroundColor: Colors.white,
buttonColor: Colors.black,
unselectedWidgetColor: Colors.white,
primaryTextTheme:
new TextTheme(caption: new TextStyle(color: Colors.white)));
----theme_bloc.dart---
import 'package:bloc/bloc.dart';
abstract class ThemeEvent {}
class ChangeTheme extends ThemeEvent{
@override
String toString() => 'ChangeTheme';
}
class ThemeBloc extends Bloc<ThemeEvent,bool>{
void changeTheme(){
dispatch(ChangeTheme());
}
@override
bool get initialState => true;
@override
void onTransition(Transition<ThemeEvent, bool> transition) {
print(transition.toString());
}
@override
Stream<bool> mapEventToState(bool state, ThemeEvent event) async* {
if(event is ChangeTheme){
yield !state;
}
}
}
结论:UI层和业务逻辑分开,渲染只需要将值传入UI组件即可。
效果图:

