Flutter UI使用Provide实现主题切换

2019-08-2119:59:21APP与小程序开发Comments1,872 views字数 2846阅读模式

provide是谷歌官方出品的一个状态管理框架 flutter-provide,它允许在小部件树中传递数据,它被设计为ScopedModel的替代品,允许我们更加灵活地处理数据类型和数据文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

为什么需要状态管理

在进行项目的开发时,我们往往需要管理不同页面之间的数据共享,在页面功能复杂,状态达到几十个上百个的时候,我们会难以清楚的维护我们的数据状态,本文将以主题切换这个功能使用状态管理来讲解如何在Flutter中使用provide这个状态管理框架文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

为什么选择Provide

一开始项目使用的是ScopedModel,使用ScopedModel可以分离展示逻辑和业务逻辑,而且简单易用,但是ScopedModel有一些局限文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

  • 如果模型较为复杂,当状态更新时,会有较多的不必要的更新

使用Provide文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

  • 当状态发生变化时,widget树会更新指定的节点,不会进行整颗widget树的更新
  • Provide有泛型的优势,相当于namespace的特性,使用过vuex的应该知道namespace的重要性,它将我们的状态分离开来
  • Provide被设计为ScopedModel的替代品,同样也有和ScopedModel的易用性
  • Provide提供了Provide.stream可以以处理流的方式处理数据,不过目前还存在一些问题

项目地址

flutter-ui, 可参考项目中使用provide方法文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

效果

Flutter UI使用Provide实现主题切换文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

如何使用

添加依赖

查看 pub-install文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

  • 在pubspec.yaml中引入依赖
dependencies:
    provide: ^1.0.2 #数据管理层
复制代码
  • 执行
flutter packages get
复制代码
  • 在需要使用的页面中引入
import 'package:provide/provide.dart'
复制代码

创建model (这才第一步)

新建 lib/store/models/config_state_model.dart 文件文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show ChangeNotifier

class ConfigInfo {
    String theme = 'red';
}
class ConfigModel extends ConfigInfo with ChangeNotifier {
    Future $setTheme(payload) async {
        theme = payload;
        notifyListeners();
    }
}
复制代码

用法同ScopedModel差不多,不过不需要继承Model类,只需要混入ChangeNotifier,通过notifyListeners通知听众刷新文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

封装Store (没错,到这里已经要快完成所有步骤了)

新建 lib/store/index.dart 文件文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

import 'package:flutter/material.dart'
import 'package:provide/provide.dart'
    show
        Providers
        Provider,
        Provide,
        ProviderNode;
import './models/config_state_model.dart' show ConfigModel;

class Store {
    //  我们将会在main.dart中runAPP实例化init
    static init({model, child, dispose = true}) {
        final providers = Providers()
            ..provide(Provider.value(ConfigModel()));
        return ProviderNode(
            child: child,
            providers: providers,
            dispose: dispose
        );
    }
    
    //  通过Provide小部件获取状态封装
    static connect<T>({builder, child, scope}) {
        return Provide<T>(
            builder: builder,
            child: child,
            scope: scope
        );
    }
    
    //  通过Provide.value<T>(context)获取封装
    static T value<T>(context, {scope}) {
        return Provide.value<T>(context, scoped: scoped);
    }
}
复制代码

需要管理多个状态只需要文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

final providers = Providers() ..provide(Provider.value(ConfigModel())) ..provide(Provider.value(More()));文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

定义全局的Provide (倒数第二)

lib/main.dart 文件文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

import 'package:flutter/material.dart';
import 'package:efox_flutter/store/index.dart'
    show Store, ConfigModel;

// 将状态放入到顶层
void main() => runApp(Store.init(child: MainApp()));
class MainApp extends StatefulWidget {
    @override
    MainAppState createState() => MainAppState();
}
class MainAppState extends State<MainApp> {
    @override
    Widget build(BuildContext context) {
        //  获取Provide状态
        return Store.connect<ConfigModel>(
            builder: (context, child, model) {
                return MaterialApp(
                    theme: ThemeData(
                        primaryColor: Color(model.theme)
                    )
                );
            }
        );
    }
}

复制代码

改变主题状态 (完成)

import 'package:flutter/material.dart';
import 'package:efox_flutter/store/index.dart'
    show ConfigModel, Store;

/**
* name: 颜色名称 如 red
* color:颜色值
* context: 上下文
*/
Widget Edage(name, color, context) {
    return GestrueDetector(
        onTap: () {
            // 修改主题状态
            Store.value<ConfigModel>(context).$setTheme(name)
        }
        child: Container(
            color: Color(color),
            height: 30,
            widtg: 30
        )
    );
}

作者:YYDev
链接:https://juejin.im/post/5ca5e240f265da30c1725021
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html

文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/15724.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/xcx/15724.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定