Flutter状态监听插件state_watcher的使用

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

Flutter状态监听插件state_watcher的使用

引言

state_watcher 是一个用于Flutter应用的状态管理解决方案。它简单且强大,适用于需要状态管理的应用场景。

指南

在应用程序中,全局状态可以被视为一组独立的真相来源和派生状态,这些派生状态由它们和其他状态计算得出。例如,在计数器应用中,整个应用只有一个唯一的真相来源:计数器。

state_watcher 中,这样的状态由 Provided 声明:

// 我们在这里声明一个初始值为0的状态,并通过`refCounter`引用。
final refCounter = Provided((_) => 0);

实际的状态存储在称为 Store 的对象中。对于Flutter应用,我们可以在widget树中声明一个新的store,使用 StateStore widget:

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    // 根store可以在MaterialApp上方声明,以便在整个应用中访问。
    return const StateStore(
      child: MaterialApp(
        home: MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}

为了显示我们的计数器的值,我们需要获取store。我们可以在任何widget中使用 WatcherBuilder 来实现这一点!

WatcherBuilder(
  builder: (BuildContext context, BuildStore store) {
    // 多亏了WatcherBuilder,我们可以从最近的StateStore祖先获取store。
    // 使用这个store,我们可以观察`refCounter`引用的状态。
    // 每当状态发生变化时,WatcherBuilder的构建函数将再次被调用。
    final counter = store.watch(refCounter);
    return Text('$counter');
  },
),

现在我们需要能够更新实际状态。为此,我们仍然需要一个store。我们可以创建另一个 WatcherBuilder 并使用store来更新值,但这可能会很繁琐。相反,我们将创建一个扩展 WatcherStatelessWidget 的专用widget!

WatcherStatelessWidget 类似于 StatelessWidget,只是它的构建方法签名不同,在其中我们可以获取store:

class _IncrementButton extends WatcherStatelessWidget {
  const _IncrementButton();

  [@override](/user/override)
  Widget build(BuildContext context, BuildStore store) {
    // 和WatcherBuilder一样,我们可以获取store。
    return FloatingActionButton(
      tooltip: 'Increment',
      onPressed: () {
        // 然后我们可以使用update方法来更改UI。
        store.update(refCounter, (x) => x + 1);
      },
      child: const Icon(Icons.add),
    );
  }
}

我们已经看到了使用 state_watcher 创建应用程序所需的基本知识,但如果我们想创建一个派生状态呢?例如,假设我们希望另一个widget显示计数器是否可以被3整除。

这样的状态由 Computed 声明:

final refDivisibleByThree = Computed((watch) {
  final counter = watch(refCounter);
  final divisibleByThree = (counter % 3) == 0;
  return divisibleByThree;
});

我们可以像 Provided 一样观察它:

class _DivisibleByThree extends WatcherStatelessWidget {
  const _DivisibleByThree();

  [@override](/user/override)
  Widget build(BuildContext context, BuildStore store) {
    final divisibleByThree = store.watch(refDivisibleByThree);
    return Text('$divisibleByThree');
  }
}

默认情况下,_DivisibleByThree widget只有在新计算值与之前不同的时候才会重建。因此,当计数器从7变为8时,_DivisibleByThree widget不会重建,因为divisibleByThree 对于这两个值都是 false

开发者工具

state_watcher 具有一个开发者工具扩展,允许你轻松调试应用中的状态变化,并查看哪个状态导致了某个widget的重建。

完整示例代码

以下是完整的示例代码,展示了如何使用 state_watcher 创建一个简单的计数器应用:

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

// 这是如何使用state_watcher编写默认计数器应用的示例。

/// 计数器值的引用。初始化为0。
final _refCounter = Provided((_) => 0);

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    // store是实际状态存储的地方。
    // 通过创建一个StateStore,所有后代都可以访问到store。
    return const StateStore(
      child: MaterialApp(
        home: _MyHomePage(),
      ),
    );
  }
}

class _MyHomePage extends StatelessWidget {
  const _MyHomePage();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('示例'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('您已经按下了按钮次数:'),

            // WatcherBuilder是一个提供最近store给其构建器的小部件。
            WatcherBuilder(
              builder: (context, store) {
                // 每当计数值改变时,此构建器将再次被调用。
                final counter = store.watch(_refCounter);
                return Text('$counter');
              },
            ),
          ],
        ),
      ),
      floatingActionButton: const _IncrementButton(),
    );
  }
}

// 不必每次创建WatcherBuilder,我们可以创建一个扩展WatcherStatelessWidget的widget。
class _IncrementButton extends WatcherStatelessWidget {
  const _IncrementButton();

  [@override](/user/override)
  Widget build(BuildContext context, BuildStore store) {
    // 在WatcherStatelessWidget的构建方法中,我们提供了store。
    return FloatingActionButton(
      tooltip: '增加',
      onPressed: () {
        // 我们可以使用store来更新由_refCounter引用的状态。
        store.update(_refCounter, (x) => x + 1);
      },
      child: const Icon(Icons.add),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter中使用state_watcher插件来进行状态监听的代码示例。这个插件允许你更轻松地监听和管理应用中的状态变化。

首先,确保你已经将state_watcher插件添加到你的Flutter项目中。你可以在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  state_watcher: ^x.y.z  # 请替换为最新版本号

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

以下是一个简单的示例,展示如何使用state_watcher来监听和管理状态:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> with WatcherMixin {
  // 创建一个状态变量
  final StringWatcher stringWatcher = StringWatcher("Initial Value");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('State Watcher Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Current Value: ${stringWatcher.value}',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 更新状态变量的值
                stringWatcher.value = "New Value";
              },
              child: Text('Update Value'),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    // 监听状态变量的变化
    stringWatcher.addListener(() {
      // 当状态变量变化时,调用setState来更新UI
      setState(() {});
    });
  }

  @override
  void dispose() {
    // 移除监听器
    stringWatcher.removeListener(this);
    super.dispose();
  }
}

解释

  1. 依赖导入:首先,我们在pubspec.yaml文件中添加了state_watcher依赖,并在代码中导入它。

  2. 状态变量:我们创建了一个StringWatcher实例,它是一个可以监听其值变化的字符串状态变量。

  3. UI构建:在build方法中,我们构建了一个简单的UI,包括一个显示当前值的Text和一个用于更新值的ElevatedButton

  4. 监听变化:在initState方法中,我们为stringWatcher添加了一个监听器。当stringWatcher的值发生变化时,监听器会调用setState方法,从而触发UI更新。

  5. 移除监听器:在dispose方法中,我们移除了监听器,以避免内存泄漏。

通过这种方式,你可以轻松地在Flutter应用中使用state_watcher插件来监听和管理状态变化。希望这个示例对你有所帮助!

回到顶部