flutter使用fishredux管理数据后自定义TabController

flutter使用fishredux管理数据后自定义TabController

flutter小白踩坑记。
学习flutter,之前一直写的vue,也写过react,习惯于数据状态管理的flutter小白总想也找个flutter数据管理的插件做个数据统一管理,于是网上到处搜索了解,好乱啊,像vue就一个vuex直接用,方便非常(虽然也可以用redux)。找来找去,最后选了咸鱼团队的fishredux,一番折腾后,终于弄上去了,开森。可是接下来的问题一大堆,使用了fishredux管理数据后,很多写法都变了,心里再次迎来一万头马,mmp,坑来了!!!!最糟糕的是fishredux没有任何官方文档(反正我没找到)!!!

使用TabBarView后,TabController要怎么搞?

很明显以前的写法没法用了!
使用fishredux之前是这么写的

TabController mController;
 Widget build(BuildContext context) {
@override
  void initState() {
    super.initState();
    mController = TabController(
      length: tabTitles.length,
      vsync: this,
    );
  }
  Widget _tabBarView() {
    return TabBarView(
      controller: mController,
      children: tabTitles.map((item) {
        return Container();
      }).toList(),
    );
  }
  }
  

用上了fishredux以后,这样写法直接报错啊,头大,一番折腾之后,终于找到了解决办法!
下面是我的部分目录结构,也是需要修改的部分
在这里插入图片描述

1.首先新建component.dart页面

component.dart页面代码如下

import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action;//注意这里
import 'state.dart';

class PersonListComponent extends ComponentState<PersonListState> with SingleTickerProviderStateMixin{
  @override
  PersonListComponent createState() => PersonListComponent();
}

注意这一行:import ‘package:flutter/material.dart’ hide Action;
后面的 hide Action,就是隐藏Action组件的意思,因为fishredux的Action和flutter本身的Action组件冲突了,这里将flutter本身的Action组件隐藏不引用。

然后再view.dart中声明tabbar切换的数据,即tab导航按钮数据

import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';

import 'tabBarComponents/AllPerson.dart';
import 'tabBarComponents/ToLoanPerson.dart';
import 'tabBarComponents/TransactionPerson.dart';
import 'tabBarComponents/WorkPerson.dart';
import 'tabBarComponents/ExitPerson.dart';

import 'action.dart';
import 'state.dart';

import 'package:labour_app/globalComponents/TopTabBar.dart';//我的TopTabBar是存放在globalComponents文件夹中
//tabList是tabbar切换的数据
List tabList = [
  {
    "title":'全部人员',
    "widget":AllPerson(),
    "index":0,
  },
  {
    "title":'在场人员',
    "widget":WorkPerson(),
    "index":1,
  },
  {
    "title":'退场人员',
    "widget":ExitPerson(),
    "index":2,
  },
  {
    "title":'异动人员',
    "widget":TransactionPerson(),
    "index":3,
  },
];
var personType=0;//人员类型
_renderPersonList(int index,List persons){
Widget buildView(PersonListState state, Dispatch dispatch, ViewService viewService) {
  return MaterialApp(
    theme: ThemeData(
      brightness: Brightness.light,
      primaryColor: Colors.white,
      textTheme: TextTheme(
        title: TextStyle(fontSize: 18.0,),
      ),
    ),
    home: Scaffold(
      backgroundColor: Color(0xFFf5f5f5),
      appBar: AppBar(
        title: Text('劳务人员'),
        leading: GestureDetector(
          onTap:(){
          //顺便提一下,在view.dart里面可以在viewService中找到context,等下告诉你我是怎么找到的
            Navigator.of(viewService.context).pop();
          },
          child: Icon(Icons.arrow_back_ios,color: Colors.grey,),
        ),
        centerTitle: true,
      ),
      body: Column(
        children: <Widget>[
          Container(
            color: Color(0xffffffff),
            height: 50.0,
             //这里将tabBar组件提出去封装了
            child:  TopTabBar(tabList:tabList,controller:state.controller),
          ),
          //TabBarView外层加上Expanded,不然会报错,具体报啥忘了,感兴趣的自己去试
          Expanded(
            child: TabBarView(
              controller: state.controller,//这里从state中取出controller赋值给TabBarView的controller即可
              children: tabList.map((item) {
                return Container(
                    child:Text('页面')
                );
              }).toList(),
            ),
          )
        ],
      ),
    ),
  );
}

TopTabBar组件,我的TopTabBar是存放在globalComponents文件夹中

import 'package:flutter/material.dart';

class TopTabBar extends StatefulWidget {
  @override
  final List tabList;
  final TabController controller;
  TopTabBar({
    Key key,
    @required this.tabList,
    @required this.controller
}):super(key:key);
  @override
  TopTabBarState createState() => TopTabBarState();
}

class TopTabBarState extends State<TopTabBar>{
  @override
  Widget build(BuildContext context) {
    return TabBar(
      isScrollable: true,
      //是否可以滚动
      controller: widget.controller,
      labelColor: Color(0xff248bfe),
      unselectedLabelColor: Color(0xff666666),
      labelStyle: TextStyle(fontSize: 16.0),
      tabs: widget.tabList.map((item) {
        return Tab(
          text: item["title"],
        );
      }).toList(),
      onTap:(index){
        print(index);
      },
    );
  }
}

state.dart中

import 'dart:ui';

import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';

class PersonListState implements Cloneable<PersonListState>, GlobalBaseState{

  PersonListState clone() {
    return PersonListState();
  }
  @override
  TabController controller;
  @override
  Color themeColor;
}

PersonListState initState(Map<String, dynamic> args) {
  return PersonListState();
}

reducer.dart中

import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action;
import 'package:labour_app/views/PersonList/view.dart';

import 'action.dart';
import 'state.dart';

Reducer<PersonListState> buildReducer() {
  return asReducer(
    <Object, Reducer<PersonListState>>{
      PersonListAction.changeTabListAction: _onInItController,
    },
  );
}

//初始化controller控制
PersonListState _onInItController(PersonListState state, Action action) {
  TabController controller =action.payload["controller"] ?? null;
  final PersonListState newState = state.clone();
  newState.controller=controller;
  return newState;
}

page.dart中

import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action;//这里注意,要隐藏Action类

import 'effect.dart';
import 'reducer.dart';
import 'state.dart';
import 'view.dart';
import 'component.dart';

class PersonListPage extends Page<PersonListState, Map<String, dynamic>> {
  PersonListPage()
      : super(
            initState: initState,
            effect: buildEffect(),
            reducer: buildReducer(),
            view: buildView,
            dependencies: Dependencies<PersonListState>(
                adapter: null,
                slots: <String, Dependent<PersonListState>>{
                }),
            middleware: <Middleware<PersonListState>>[
            ],);
            
  //这下面几行是创建component.dart后必须加的
  @override
  ComponentState<PersonListState> createState() {
    return PersonListComponent();
  }

}

effect.dart中
偷偷告诉你一个惊天秘密,在view.dart中声明的变量在effect.dart中可以看到哦!!我的天哪,还有这操作!!所以我在view.dart中声明的tabList数据变量可以在effect.dart中直接拿来使用!

再告诉你一个惊天发现,我是从这里判断到view.dart可以从viewService中取到context的,我们来分分析一下:
void _initController(Action action,Context ctx){
ctx.dispatch(PersonListActionCreator.onChangeTabListAction({tabList:tabList,‘controller’:_controller}));
}

从这里可以看到,effect中有ctx,而其他几个文件是没有的
然后再看看view.dart中

Widget buildView(PersonListState state, Dispatch dispatch, ViewService viewService) {})

按我web端的思想,要想取到context,最先想到的是this中,可是再这里直接写this报错,那么就只能从参数中尝试
Widget buildView总共三个参数。第一个state,不用猜就是state.dart里面的东西;第二个dispatch,用过 vuex 或者 redux 想必都很清楚,这是 action 的东西,何况这插件叫f ishredux ,那么就只剩下第三个viewService,看字面意思,不久视图服务嘛?而 context也是界面,果断试了下 viewService.context ,成功!!

import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action; //注意要隐藏Actio类
import 'package:flutter/widgets.dart' hide Action;  //注意要隐藏Actio类
import 'package:labour_app/views/PersonList/view.dart';
import 'action.dart';
import 'state.dart';

Effect<PersonListState> buildEffect() {
  return combineEffects(<Object, Effect<PersonListState>>{
       Lifecycle.initController: _initController, //页面初始化监听tabbar控制
  });
}
void _initController(Action action,Context<PersonListState> ctx){
  final TickerProvider tickerProvider = ctx.stfState  as TickerProvider;
  var _controller =TabController(vsync: tickerProvider,length: tabList.length);
  _controller.addListener((){
    println(_controller.index);
  });
  ctx.dispatch(PersonListActionCreator.onChangeTabListAction({tabList:tabList,'controller':_controller}));
}

action.dart中


import 'package:fish_redux/fish_redux.dart';

//TODO replace with your own action
enum PersonListAction {
  changeTabListAction
}
  //tabbar contruller
  static Action onChangeTabListAction(params) {
  /*
  params是effect.dart中ctx.dispatch(PersonListActionCreator.onChangeTabListAction({tabList:tabList,'controller':_controller})); 传递来的参数,
  即params就是{tabList:tabList,'controller':_controller}
  action里通过payload接收
  */
    return Action(PersonListAction.changeTabListAction,payload:params);
  }]
}

好了,运行下试试,搞定!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值