Flutter

8、Flutter状态管理provider用法

2019-10-11  本文已影响0人  LogMan

之前学习Flutter,跟网上大神教程写了一个购物的APP,里面提供的状态管理工具是provide,几个月过后,Flutter官方发布provider代替provide,成为最新的状态管理工具,例外,新的provider支持Flutter_web的开发,亲测好用。

用法:

1、在项目的 pubspec.yml 添加 provider

dependencies:
  provider: ^3.1.0

2、构建混合ChangeNotifier的类,操作全局数据,使用notifyListeners方法来通知 UI 更新:
如:底部导航切换,定义当前切换卡索引--currentIndex,更改currentIndex的值,通知主页刷新底部导航UI,切换当前页面。

import 'package:flutter/foundation.dart';

class CurrentIndexProvide with ChangeNotifier{
  int currentIndex = 0;
  changeIndex(int newIndex){
    currentIndex = newIndex;
    notifyListeners();
  }
}

要使用这个ChangeNotifier状态管理类,需要用 provider 提供的 ChangeNotifierProvider 方法将数据注册到整个应用。如果有多个这样的ChangeNotifier状态管理类,就需要使用MultiProvider,用法介绍:

import 'package:flutter/material.dart';
import 'pages/index_page.dart';
import 'package:provider/provider.dart';
......
import 'provide/currentIndex.dart';

void main(){
  List<SingleChildCloneableWidget> provides = [];
  provides..add(ChangeNotifierProvider.value(value:ChildCategory()))
    ..add(ChangeNotifierProvider.value(value:CategoryGoodsListProvider()))
    ..add(ChangeNotifierProvider.value(value:DetailInfoProvide()))
    ..add(ChangeNotifierProvider.value(value:CartProvide()))
    ..add(ChangeNotifierProvider.value(value:CurrentIndexProvide()));//本文中重点介绍
  runApp(MultiProvider(providers: provides,child:MyApp()));
}

class MyApp extends StatelessWidget{
  ......
}

3、ChangeNotifierProvider 方法将数据注册到整个应用

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

import 'pages/index_page.dart';
import 'provide/currentIndex.dart';
class MyApp extends StatelessWidget{

  @override
  Widget build(BuildContext context) {
    final router = Router();
    Routers.configureRouters(router);
    Application.router = router;
    return Container(
      child: MaterialApp(
        title: '商城',
        onGenerateRoute: Application.router.generator,
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.pink,
        ),
        home: ChangeNotifierProvider(
        builder: (context) =>CurrentIndexProvide(),
        child: IndexPage(),
      ),
    );
  }
}

然后IndexPage中,使用CurrentIndexProvide中的currentIndex。
4、使用 provider 的数据首先要导入 provider 以及对应的currentIndex CurrentIndexProvide,然后用 Consumer 加类型 CurrentIndexProvide 来使用这个currentIndex

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'home_page.dart';
import 'category_page.dart';
import 'cart_page.dart';
import 'member_page.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import '../provide/currentIndex.dart';

class IndexPage extends StatelessWidget {
  final List<BottomNavigationBarItem> bottomTabs=[
    BottomNavigationBarItem(
      icon: Icon(CupertinoIcons.home),
      title: Text('首页'),
    ),
    BottomNavigationBarItem(
      icon: Icon(CupertinoIcons.search),
      title: Text('分类'),
    ),
    BottomNavigationBarItem(
      icon: Icon(CupertinoIcons.shopping_cart),
      title: Text('购物车'),
    ),
    BottomNavigationBarItem(
      icon: Icon(CupertinoIcons.profile_circled),
      title: Text('会员中心'),
    ),
  ];

  final List<Widget> tabBodies = [
    HomePage(),
    CategoryPage(),
    CartPage(),
    MemberPage()
  ];
  @override
  Widget build(BuildContext context) {
    ScreenUtil.instance = ScreenUtil(width: 750,height: 1334)..init(context);
    return Consumer<CurrentIndexProvide>(
      builder: (context, currentIndexProvide, child){
        int currentIndex = currentIndexProvide.currentIndex;
        return Scaffold(
            backgroundColor: Color.fromRGBO(244, 245, 245, 1.0),
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              currentIndex: currentIndex,
              items: bottomTabs,
              onTap: (index){ //切换导航卡
                currentIndexProvide.changeIndex(index);
              },
            ),
            body: IndexedStack(
              index: currentIndex,
              children: tabBodies,
            )
        );
      },
    );
  }
}

最后,当切换导航卡,通过调用CurrentIndexProvide中的changeIndex(index)方法,changeIndex(int newIndex){
currentIndex = newIndex; //修改状态管理中的currentIndex
notifyListeners(); // 刷新UI
}
notifyListeners() : 通知代码中使用到此provider的控件Consumer进行刷新

上一篇下一篇

猜你喜欢

热点阅读