Flutter状态分组管理插件state_groups的使用

发布于 1周前 作者 itying888 来自 Flutter

Flutter状态分组管理插件state_groups的使用

无状态状态管理解决方案

大多数状态管理解决方案过于复杂,因为它们试图同时管理内部状态和可见状态。状态分组(state groups)则不同,它只更新可见状态。你需要自己管理内部状态。这样,它可以比其他状态管理解决方案简单得多。

使用

版本0.3.1显著简化了过程。以下方法是首选,但你仍然可以使用旧方法(在最后描述)。

此包通过通知StateStatefulWidget中工作。为此,只需将你的State继承自SyncState。所以:

class FooState extends State<Foo>

变为:

class FooState extends SyncState<void, Foo>

通知

要通知给定类型的SyncState的所有实例,只需调用updateAll<T>(),其中T是你想要通知的类型。例如:

updateAll<FooState>();

如果你需要发送更复杂的消息,可以调用forEachState<T>(void Function(T)),同样地,T是你想要通知的类型。例如:

forEachState<FooState>((FooState state) {
	state.someInternalMethod();
});

使用(旧方法)

创建状态分组

首先创建一个状态分组。在这个例子中,我们将创建一个全局变量,尽管它们不一定是全局的。

StateGroup exampleStateGroup = StateGroup();

你也可以指定一个泛型类型作为消息类型。这里我们使用void,因为我们不会发送任何消息,但如果你想发送消息,你可以使用枚举代替。

StateGroup<void> exampleStateGroup = StateGroup<void>();

注册到状态分组

这里有两步。首先,将状态类改为从SyncState继承而不是从State继承。这还需要添加一个额外的泛型类型。这应该与上一步中使用的泛型类型相同。我们现在将其保持为void

class FooState extends State<Foo>

变为:

class FooState extends SyncState<void, Foo>

然后,在构造函数中调用super并传递你想要订阅的状态分组。

FooState() : super(exampleStateGroup);

通知状态分组

现在,你可以随时通知StateGroup,当所有成员都需要更新时,或者检查它们是否需要更新。为此,使用notifyAll()命令,如下所示:

exampleStateGroup.notifyAll();

就这样。StateGroup会自动处理其余的一切。

SyncStateBuilder

如果上述方法对你来说太麻烦了,还有SyncStateBuilder<T>,它作为一个SyncState<void>工作。如果你只需要UI在收到通知时更新,这已经足够了,但它不支持自定义更新行为。

完整示例

以下是完整的示例代码:

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

StateGroup<void> exampleStateGroup = StateGroup<void>();

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({required this.title, super.key});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends SyncState<void, MyHomePage> {

  _MyHomePageState() : super(exampleStateGroup);

  int _counter = 0;

  // 正常情况下我们会在这里使用setState()调用,但由于我们使用状态分组,我们不必这样做
  void _incrementCounter() {
    _counter++;
    exampleStateGroup.notifyAll();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '你已经按下了按钮多少次:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: '增加',
        child: const Icon(Icons.add),
      ),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用state_groups插件进行状态分组管理的代码示例。state_groups插件允许你将多个状态组合在一起管理,从而简化复杂的状态管理逻辑。

首先,确保你已经在pubspec.yaml文件中添加了state_groups依赖:

dependencies:
  flutter:
    sdk: flutter
  state_groups: ^latest_version  # 请替换为最新的版本号

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

接下来,让我们看一个具体的代码示例。

示例代码

  1. 定义状态组

首先,定义一个状态组,它将包含多个状态。

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

class MyStateGroup extends StateGroup {
  bool isLoading = false;
  String errorMessage = '';
  int counter = 0;

  void incrementCounter() {
    setState(() {
      counter++;
    });
  }

  Future<void> loadData() async {
    setState(() {
      isLoading = true;
      errorMessage = '';
    });

    // 模拟异步操作,例如从网络获取数据
    await Future.delayed(Duration(seconds: 2));

    if (/* 数据加载成功 */) {
      setState(() {
        isLoading = false;
      });
    } else {
      setState(() {
        isLoading = false;
        errorMessage = 'Failed to load data';
      });
    }
  }
}
  1. 创建Flutter应用

接下来,创建一个Flutter应用来使用这个状态组。

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter State Groups Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with StateGroupListener<MyStateGroup> {
  @override
  void initState() {
    super.initState();
    // 监听状态组的变化
    listenToStateGroup(MyStateGroup.instance);
  }

  @override
  Widget build(BuildContext context) {
    final stateGroup = MyStateGroup.instance;

    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter State Groups Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${stateGroup.counter}',
              style: Theme.of(context).textTheme.headline4,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: stateGroup.isLoading ? null : stateGroup.incrementCounter,
              child: Text('Increment'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => stateGroup.loadData(),
              child: Text('Load Data'),
            ),
            SizedBox(height: 20),
            if (stateGroup.isLoading)
              CircularProgressIndicator()
            else if (stateGroup.errorMessage.isNotEmpty)
              Text(
                stateGroup.errorMessage,
                style: TextStyle(color: Colors.red),
              ),
          ],
        ),
      ),
    );
  }

  @override
  void onStateChanged(MyStateGroup stateGroup) {
    // 当状态组发生变化时,这里会自动调用,但在这个例子中我们不需要额外处理
    // 因为我们已经在build方法中使用了状态组的状态
    setState(() {});
  }
}
  1. 初始化状态组

在应用的某个地方(通常在main.dart文件的顶部),你需要初始化状态组实例:

void main() {
  // 初始化状态组实例
  MyStateGroup.instance = MyStateGroup();
  runApp(MyApp());
}

说明

  • MyStateGroup 类继承自 StateGroup,并包含多个状态字段(isLoading, errorMessage, counter)和状态更新方法(incrementCounter, loadData)。
  • MyHomePage 是一个有状态的Widget,通过 with StateGroupListener<MyStateGroup> 混入监听状态组的变化。
  • initState 方法中,通过 listenToStateGroup(MyStateGroup.instance) 开始监听状态组的变化。
  • build 方法中,根据状态组的状态构建UI。
  • 使用 setState 在UI中反映状态变化。

这样,你就可以使用 state_groups 插件在Flutter应用中管理复杂的状态了。希望这个示例对你有帮助!

回到顶部