Flutter

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组件即可。
效果图:

image.png
image.png
上一篇 下一篇

猜你喜欢

热点阅读