Flutter状态管理插件flutter_value_notifier_stateful_widget的使用

Flutter状态管理插件flutter_value_notifier_stateful_widget的使用

这个Flutter包提供了一个极其简单的状态管理系统,特别适用于那些需要响应事件处理器(如onTap)变化的组件。ValueNotifierStatefulWidgetValueNotifierValueListenableBuilder的功能合并到一个类中,并为你管理ValueNotifier的生命周期。

ValueNotifierStatefulWidget允许你避免每次需要组件显示响应简单状态变化时都要创建一个新的StatefulWidget类。这使得你可以在StatelessWidget中设置状态行为,从而大幅简化你的组件代码。

每个组件只能管理一个状态值,但这一功能已经涵盖了广泛的应用场景。

使用方法

包裹状态依赖组件

许多Flutter组件(如复选框、单选按钮、开关等)需要包裹在StatefulWidget中来跟踪它们的选择状态。ValueNotifierStatefulWidget极大地简化了这一点。

之前:

class SwitchWidget extends StatefulWidget {
  const SwitchWidget({super.key});

  @override
  State<SwitchWidget> createState() => _SwitchWidgetState();
}

class _SwitchWidgetState extends State<SwitchWidget> {
  bool switchedOn = false;

  @override
  Widget build(BuildContext context) {
    return Switch(
      value: switchedOn,
      onChanged: (bool value) => setState(() => switchedOn = value),
    );
  }
}

之后:

ValueNotifierStatefulWidget(
  initialValue: false,
  builder: (context, switchedOn) => Switch(
    value: switchedOn.value,
    onChanged: (bool value) => switchedOn.value = value,
  ),
)
在异步间隔后改变状态
ValueNotifierStatefulWidget<bool>(
  initialValue: false,
  builder: (BuildContext context, ValueNotifier<bool> isLoading) => 
    ElevatedButton.icon(
      style: ElevatedButton.styleFrom(
        backgroundColor: Colors.blue,
        foregroundColor: Colors.white,
        disabledBackgroundColor: Colors.blue.shade200,
        disabledForegroundColor: Colors.white,
      ),
      // 按钮图标:加载时显示一个进度条,否则显示一个勾选图标
      icon: isLoading.value
          ? const SizedBox(
              width: 15,
              height: 15,
              child: CircularProgressIndicator(
                color: Colors.white,
                strokeWidth: 2.5,
              ),
            )
          : const Icon(
              Icons.check,
              color: Colors.white,
            ),
      // 按钮文本
      label: const Text(
        '提交',
        style: TextStyle(fontSize: 15),
      ),
      // 加载时禁用按钮
      onPressed: isLoading.value
          ? null
          : () async {
              try {
                // 设置加载状态为true
                isLoading.value = true;
                // 调用异步函数
                await doSomethingAsynchronously();
              } finally {
                // 设置加载状态为false(在finally块中完成,以防异步函数抛出错误)
                isLoading.value = false;
              }
            },
    ),
);
传入自己的ValueNotifier

ValueNotifierStatefulWidget构造函数可以接受一个valueNotifier参数,在这里你可以传入自己的ValueNotifier<T>,从而使状态可以从外部管理。这使得ValueNotifierStatefulWidget的工作方式类似于ValueListenableBuilder

ValueNotifierStatefulWidget(
  valueNotifier: myCustomValueNotifier,
  builder: (context, myCustomValueNotifier) => // 构建你的组件
)

safeSetState

该库还提供了safeSetState扩展,作为State的扩展,它允许你在任何时候调用setState,包括在处理程序回调中等待异步函数之后,而不会遇到小部件不再挂载的问题。当ValueNotifier的值发生变化时,会调用safeSetState,这对于在异步函数中进行状态更新非常重要。

extension SafeUpdateState on State {
  void safeSetState(void Function() updaterFunction) {
    void callSetState() {
      // 只有在已挂载的情况下才能调用setState
      if (mounted) {
        // ignore: invalid_use_of_protected_member
        setState(updaterFunction);
      }
    }
    if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
      // 当前正在构建,不能调用setState -- 添加帧后回调
      SchedulerBinding.instance.addPostFrameCallback((_) => callSetState());
    } else {
      callSetState();
    }
  }
}

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

1 回复

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


当然,以下是一个关于如何使用 flutter_value_notifier_stateful_widget 插件进行状态管理的代码示例。这个插件提供了一种便捷的方式来将 ValueNotifierStatefulWidget 结合使用,使得状态管理更加直观和高效。

首先,确保在你的 pubspec.yaml 文件中添加依赖:

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

然后运行 flutter pub get 来获取依赖。

下面是一个完整的示例,展示了如何使用 flutter_value_notifier_stateful_widget

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter ValueNotifier Stateful Widget Demo'),
        ),
        body: ValueNotifierProvider<int>(
          create: (_) => ValueNotifier<int>(0),
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ValueNotifierStatefulBuilder<int>(
      valueListenable: ValueNotifierProvider.of<int>(context),
      builder: (context, value, child) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Current Value: $value',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                final valueNotifier = ValueNotifierProvider.of<int>(context);
                valueNotifier.value++;
              },
              child: Text('Increment'),
            ),
          ],
        );
      },
    );
  }
}

代码解释

  1. 依赖注入:

    • flutter_value_notifier_stateful_widget 提供了 ValueNotifierProvider 组件,用于在应用树的某个位置创建并提供一个 ValueNotifier 实例。
    • MyApp 中,我们使用 ValueNotifierProvider 创建了一个 ValueNotifier<int> 实例,并将其传递给 MyHomePage
  2. 状态消费:

    • MyHomePage 是一个 StatelessWidget,它使用 ValueNotifierStatefulBuilder 来消费 ValueNotifier 的值。
    • ValueNotifierStatefulBuilder 是一个便利组件,它允许我们监听 ValueNotifier 的变化并重建 UI。
  3. 状态更新:

    • 通过调用 ValueNotifierProvider.of<int>(context) 获取 ValueNotifier 实例,并调用其 value 属性来更新状态。
    • 当按钮被点击时,ValueNotifier 的值会增加,这会触发 ValueNotifierStatefulBuilderbuilder 函数重新构建 UI。

这个示例展示了如何使用 flutter_value_notifier_stateful_widget 插件进行简单的状态管理。如果你的应用有更复杂的状态管理需求,可能需要考虑使用更强大的状态管理解决方案,如 ProviderRiverpodBloc

回到顶部