今天学习下Flutter
中state管理的第三方redux
. 其中,redux: 3.0.0
flutter_redux: 0.5.3
代码结构如图所示:
下面是各文件的源码. main.dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux/redux.dart'; import 'package:redux_demo/model/count_state.dart'; import 'package:redux_demo/top_screen.dart'; void main() { final store = Store<CountState>(reducer, initialState: CountState.initState()); runApp(new MyApp(store)); } class MyApp extends StatelessWidget { final Store<CountState> store; MyApp(this.store); @override Widget build(BuildContext context) { return StoreProvider<CountState>( store: store, child: new MaterialApp( title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home: TopScreen(), ), ); } }
tabbar.dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 import 'package:flutter/material.dart'; import 'package:redux_demo/one/one.dart'; import 'package:redux_demo/two/two.dart'; class Tabbar extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( debugShowCheckedModeBanner: false, home: new MainPageWidget()); } } class MainPageWidget extends StatefulWidget { @override State<StatefulWidget> createState() { return new MainPageState(); } } class MainPageState extends State<MainPageWidget> { int _tabIndex = 0; var tabImages; var appBarTitles = ['One', 'Two']; /* * 存放二个页面,跟fragmentList一样 */ var _pageList; /* * 根据选择获得对应的normal或是press的icon */ Image getTabIcon(int curIndex) { if (curIndex == _tabIndex) { return tabImages[curIndex][1]; } return tabImages[curIndex][0]; } /* * 获取bottomTab的颜色和文字 */ Text getTabTitle(int curIndex) { if (curIndex == _tabIndex) { return new Text(appBarTitles[curIndex], style: new TextStyle(fontSize: 14.0, color: const Color(0xff1296db))); } else { return new Text(appBarTitles[curIndex], style: new TextStyle(fontSize: 14.0, color: const Color(0xff515151))); } } /* * 根据image路径获取图片 */ Image getTabImage(path) { return new Image.asset(path, width: 24.0, height: 24.0); } void initData() { /* * 初始化选中和未选中的icon */ tabImages = [ [ getTabImage('images/tab/one.png'), getTabImage('images/tab/one_active.png') ], [ getTabImage('images/tab/two.png'), getTabImage('images/tab/two_active.png') ], ]; /* * 子界面 */ _pageList = [ new One(), new Two(), ]; } @override Widget build(BuildContext context) { //初始化数据 initData(); return Scaffold( body: _pageList[_tabIndex], bottomNavigationBar: new BottomNavigationBar( items: <BottomNavigationBarItem>[ new BottomNavigationBarItem( icon: getTabIcon(0), title: getTabTitle(0)), new BottomNavigationBarItem( icon: getTabIcon(1), title: getTabTitle(1)), ], type: BottomNavigationBarType.fixed, //默认选中首页 currentIndex: _tabIndex, iconSize: 24.0, //点击事件 onTap: (index) { setState( () { _tabIndex = index; }, ); }, ), ); } }
top_screen.dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import 'package:flutter/material.dart'; import 'package:redux_demo/tabbar.dart'; class TopScreen extends StatefulWidget { @override _TopScreenState createState() => _TopScreenState(); } class _TopScreenState extends State<TopScreen> { @override Widget build(BuildContext context) { return Tabbar(); } }
count_state.dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import 'package:meta/meta.dart'; /* * State中所有属性都应该是只读的 */ @immutable class CountState { final int _count; get count => _count; CountState(this._count); CountState.initState() : _count = 0; } /* * 定义操作该State的全部Action * 这里只有增加count一个动作 */ enum Action { increment } /* * reducer会根据传进来的action生成新的CountState */ CountState reducer(CountState state, action) { //匹配Action if (action == Action.increment) { return CountState(state.count + 1); } return state; }
one.dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux_demo/model/count_state.dart'; class One extends StatefulWidget { @override _OneState createState() => _OneState(); } class _OneState extends State<One> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('one Screen'), ), body: Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Text( 'You have pushed the button this many times:', ), StoreConnector<CountState,int>( converter: (store) => store.state.count, builder: (context, count) { return Text( count.toString(), style: Theme.of(context).textTheme.display1, ); }, ), ], ), ), floatingActionButton: StoreConnector<CountState,VoidCallback>( converter: (store) { return () => store.dispatch(Action.increment); }, builder: (context, callback) { return FloatingActionButton( onPressed: callback, child: Icon(Icons.add), ); }, ), ); } }
two.dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux_demo/model/count_state.dart'; class Two extends StatefulWidget { @override _TwoState createState() => _TwoState(); } class _TwoState extends State<Two> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('two Screen'), ), body: Center( child: StoreConnector<CountState, int>( converter: (store) => store.state.count, builder: (context, count) { return Text( count.toString(), style: Theme.of(context).textTheme.display1, ); }, ), ), ); } }
效果图:
源码
另外:其他管理库学习
另外:Flutter学习demo