Flutter状态共享插件inherited_store的使用

Flutter状态共享插件inherited_store的使用

inherited_store 是一个持有数据并重建依赖于更改数据的小部件的继承小部件。此包以 InharitedModel 作为其基础。

优点

  1. 轻量级(约100行代码)
  2. 使用Flutter自身的 InheritedModel 来检测需要重建的部分。
  3. 没有样板代码

缺点

  1. 没有计算值
  2. 使用键很麻烦

示例

示例

示例代码在示例标签页中。

开始使用

步骤1:用Store包装你的应用
Store(
  data: {
    'counter': 1,
  },
  child: MaterialApp(
    /* ... */
  ),
);
步骤2:使用它
class CounterText extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Text(Store.of(context, 'counter').get().toString()); 
  }
}

如果你编辑 counter 使用 Store.of(context,'counter').set(2),则 CounterText 小部件将自动重建。

什么会被重建?

当你调用 Store.of(context,key) 时,所有当前使用 context 的小部件都会订阅该键的变化。如果键的值发生变化,则使用订阅上下文的小部件将被重建。

例如,在下面的例子中,当 counter 修改时, 只有构建器内部的文本小部件会更新 因为它是通过 c 上下文订阅的,并且只有 c 的后代会被重建。 如果我们将 Store.of(c,'counter') 替换为 Store.of(context,'counter'),那么当 counter 改变时,整个小部件将被重建,显示时间的文本也会更新。

class StoreText extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text(DateTime.now().toString()), // 显示此文本小部件构建的时间
        Builder(builder: (c) {
          return Text(Store.of(c, 'counter').get().toString());
        }),
      ],
    );
  }
}

示例用例

不可变数据管理

存储在数据映射中的事物应仅使用 set 方法替换。

Store(
  data: {
     UnmodifiableListView<Post> : UnmodifiableListView<Post>([]), // 在列表上使用add不会通知订阅者
     User : User.getSavedUser(), 
     MyService : MyService(),
     AppTheme : AppTheme(),
     420 : false, // 键可以是任何东西
     'balance' : 12000,
  },
  child: MaterialApp(
    /* ... */
  ),
);
管理应用程序偏好设置

你可以使用 Inherited_Store 来有效地管理你的应用程序偏好设置。将偏好设置加载到 storedata 字段中,然后使用 onValueModified 回调来更新存储的偏好设置。

示例代码

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

void main() => runApp(SettingsApp());

class SettingsApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Store(
      data: {
        'counter': 1,
        'counter2': 1,
      },
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: MainPage(),
      ),
    );
  }
}

class MainPage extends StatefulWidget {
  [@override](/user/override)
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(32.0),
            child: SettingsDisplay(),
          ),
          Expanded(
            child: Row(
              children: <Widget>[
                Expanded(
                  child: Counter(
                    stKy: 'counter',
                  ),
                ),
                Expanded(
                  child: Counter(
                    stKy: 'counter2',
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: Row(
              children: <Widget>[
                Expanded(
                  child: StoreText(
                    storeKey: 'counter2',
                  ),
                ),
                Expanded(
                  child: StoreText(
                    storeKey: 'counter',
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class SettingsDisplay extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
        children: InheritedStore.of(context)
            .data
            .entries
            .map((e) => Text('${e.key} : ${e.value}'))
            .toList());
  }
}

class StoreText extends StatelessWidget {
  final String storeKey;

  const StoreText({Key? key, required this.storeKey}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        FutureBuilder(
            future: Future.delayed(Duration(milliseconds: 600)),
            builder: (c, s) {
              if (s.connectionState != ConnectionState.done) {
                return CircularProgressIndicator();
              }
              return Text(Store.of(context, storeKey).get().toString());
            }),
        Container(),
      ],
    );
  }
}

class Counter extends StatelessWidget {
  final String stKy;

  const Counter({Key? key, required this.stKy}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          FutureBuilder(
            future: Future.delayed(Duration(milliseconds: 600)),
            builder: (context, s) {
              if (s.connectionState != ConnectionState.done)
                return CircularProgressIndicator();
              return Text(Store.of(context, stKy).get().toString());
            },
          ),
          ElevatedButton(
            child: Text('increment'),
            onPressed: () {
              Store.of(context, stKy).set(Store.of(context, stKy).get() + 1);
            },
          ),
        ],
      ),
    );
  }
}

更多关于Flutter状态共享插件inherited_store的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter状态共享插件inherited_store的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


inherited_store 是一个用于 Flutter 应用中的状态管理插件,它基于 Flutter 的 InheritedWidget 机制,能够方便地在 widget 树中共享状态。InheritedWidget 是 Flutter 中用于在 widget 树中传递数据的一种机制,而 inherited_store 则在其基础上进行了封装,使得状态管理更加简便。

安装

首先,你需要在 pubspec.yaml 文件中添加 inherited_store 依赖:

dependencies:
  flutter:
    sdk: flutter
  inherited_store: ^1.0.0

然后运行 flutter pub get 来安装依赖。

基本用法

  1. 创建 Store

    Storeinherited_store 中的核心类,用于存储和管理状态。你可以通过继承 Store 来定义自己的状态管理类。

    import 'package:inherited_store/inherited_store.dart';
    
    class MyStore extends Store {
      int counter = 0;
    
      void increment() {
        counter++;
        notifyListeners(); // 通知监听者状态已更新
      }
    }
    
  2. 在 Widget 树中提供 Store

    使用 InheritedStore widget 将 Store 提供给子 widget。InheritedStore 是一个 InheritedWidget,它可以在 widget 树中传递 Store

    import 'package:flutter/material.dart';
    import 'package:inherited_store/inherited_store.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: InheritedStore(
            store: MyStore(),
            child: HomePage(),
          ),
        );
      }
    }
    
  3. 在子 Widget 中访问 Store

    在子 widget 中,你可以通过 InheritedStore.of<MyStore>(context) 来访问 Store,并且可以在状态更新时自动重建 widget。

    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final store = InheritedStore.of<MyStore>(context);
    
        return Scaffold(
          appBar: AppBar(
            title: Text('InheritedStore Example'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Counter: ${store.counter}',
                  style: Theme.of(context).textTheme.headline4,
                ),
                SizedBox(height: 20),
                ElevatedButton(
                  onPressed: store.increment,
                  child: Text('Increment'),
                ),
              ],
            ),
          ),
        );
      }
    }
回到顶部