Flutter状态管理与动作触发插件re_state_action的使用

Flutter状态管理与动作触发插件re_state_action的使用

关于

这个包是一个流行的[RxDart]库的封装,通过流简化状态管理。它提供了一个简单的解决方案来有效地处理应用程序状态,并无缝地管理用户界面(UI)和用户之间的交互。通过利用该包的反应式方法,您可以高效地处理诸如对话框、警告、模态等UI组件,同时避免不必要的状态过载。

使用

创建一个简单的ReStateAction类
// 定义一个显示Snackbar的动作接口
abstract class ShowSnackbarAction{}

// 当值为偶数时显示Snackbar的具体动作
class ShowIsEvenValueSnackbarAction extends ShowSnackbarAction{}

// CounterStateAction类负责管理计数器的状态
class CounterStateAction extends ReStateAction<int, ShowSnackbarAction> {
  CounterStateAction({int initialState = 0}) : super(initialState){
    // 在构造函数中添加状态监听器
    listenState((state){
        if(state.isEven){
         emitAction(ShowIsEvenValueSnackbarAction());
        }
    });
  }

  // 增加计数器的值
  void increment() => emitState(state + 1);
  // 减少计数器的值
  void decrement() => emitState(state - 1);
}

在这个示例中,我们利用包创建了一个CounterStateAction类,通过扩展ReStateAction类来管理计数器的状态。在类的构造函数中设置了一个监听器来监控状态变化。当状态变为偶数时,使用emitAction方法发出一个ShowIsEvenValueSnackbarAction类型的动作,这允许您处理事件并显示一个Snackbar或执行其他操作。

使用ReState类管理简单状态
class CounterReState extends ReState<int> {
  CounterReState({int initialState = 0}) : super(initialState);

  void increment() => emitState(state + 1);
  void decrement() => emitState(state - 1);
}

我们可以使用[state]getter访问状态或使用[stateStream]getter访问流。动作只能通过[actionStream]属性访问。状态和动作都是流,可以使用[listenState][listenAction]方法进行监听。

在UI中使用ReState类
ReStateWidget<int>(
  reState: counterReState,
  builder: (context, state) {
    return Text('$state');
  },
),
在UI中使用ReStateAction类
ReStateActionWidget<int, ShowSnackbarAction>(
  reState: counterReStateAction,
  onAction: (action) {
    if (action is ShowIsEvenValueSnackbarAction) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('The value is even'),
        ),
      );
    }
  },
  builder: (context, state, child) {
    return Column(
      children: [
        Text('Current value: $state'),
        TextButton(
          onPressed: () => counterReStateAction.increment(),
          child: Text('Increment'),
        ),
        TextButton(
          onPressed: () => counterReStateAction.decrement(),
          child: Text('Decrement'),
        ),
      ],
    );
  },
),
仅监听动作
ReActionListener<ShowSnackbarAction>(
  reState: counterStateAction,
  onAction: (action) {
    if (action is ShowIsEvenValueSnackbarAction) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('The value is even'),
        ),
      );
    }
  },
  child: Text('Widget that will not be rebuilt'),
),

Dart 3.0

该包兼容Dart 3.0的新特性,如密封类和模式匹配。要使用这些特性,需要将Flutter版本更新到3.10.0或更高版本,并在pubspec.yaml文件中启用Dart 3.0特性。

environment:
  sdk: ">=3.0.0 <4.0.0"

使用示例:

sealed class ShowSnackbarAction{}

class ShowIsEvenValueSnackbarAction extends ShowSnackbarAction{}

class ShowIsOddValueSnackbarAction extends ShowSnackbarAction{}

class CounterStateAction extends ReStateAction<int, ShowSnackbarAction> {
  CounterStateAction({int initialState = 0}) : super(initialState){
    listenState((state){
        if(state.isEven){
         emitAction(ShowIsEvenValueSnackbarAction());
        }else{
         emitAction(ShowIsOddValueSnackbarAction());
        }
    });
  }

  void increment() => emitState(state + 1);
  void decrement() => emitState(state - 1);
}

//... 在UI中
ReActionListener<ShowSnackbarAction>(
  reState: counterStateAction,
  onAction: (action) {
    final snackbarText = switch (action) {
          ShowIsEvenValueSnackbarAction() => 'The value is even',
          ShowIsOddValueSnackbarAction() => 'The value is odd',
          _ => 'The value is null',
        };
    
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(snackbarText),
      ),
    );
  },
  child: Text('Widget that will not被重建'),
),

示例

以下是一个完整的示例demo:

import 'package:flutter/material.dart';
import 'package:re_state_action/re_listener_modifiers.dart';
import 'package:re_state_action/re_state_action.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter ReStateAction Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter ReStateAction Demo Page'),
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  final ReCounterStateActionEvent _reCounterStateActionEvent =
      ReCounterStateActionEvent();

  void _incrementCounter() {
    _reCounterStateActionEvent.process(IncrementCounter());
  }

  void _onCounterAction(ReCounterAction action) {
    ScaffoldMessenger.of(context)
      ..removeCurrentSnackBar()
      ..showSnackBar(
        SnackBar(
          content: Text('Snackbar Color: ${action.colorName}'),
          backgroundColor: action.color,
        ),
      );
  }

  void _onResetCounter() {
    _reCounterStateActionEvent.process(ResetCounter());
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: _onResetCounter,
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            ReStateActionWidget(
              reState: _reCounterStateActionEvent,
              onAction: _onCounterAction,
              buildWhen: (previousState, currentState) {
                return currentState < 15;
              },
              builder: (context, state, child) => Text(
                '$state',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

class ReCounterStateActionEvent
    extends ReStateActionEvent<int, ReCounterAction, ReCounterEvent> {
  ReCounterStateActionEvent() : super(0) {
    on<IncrementCounter>(
      (event) => _increment(),
      modifier: ReListenerModifiers.throttleTime(const Duration(seconds: 1)),
    );
    on<ResetCounter>(
      (event) => _reset(),
      modifier: ReListenerModifiers.debounceTime(const Duration(seconds: 1)),
    );

    listenState(
      (state) {
        if (state == 0) {
          return;
        } else if (state % 2 == 0) {
          emitAction(const ShowSnackGreen());
        } else {
          emitAction(const ShowSnackRed());
        }
      },
    );
  }

  void _increment() {
    emitState(state + 1);
  }

  void _reset() {
    emitState(0);
    emitAction(const ShowSnackBrown());
  }
}

abstract class ReCounterAction {
  const ReCounterAction(
    this.color,
    this.colorName,
  );
  final Color color;
  final String colorName;
}

class ShowSnackRed extends ReCounterAction {
  const ShowSnackRed() : super(Colors.red, 'Red');
}

class ShowSnackGreen extends ReCounterAction {
  const ShowSnackGreen() : super(Colors.green, 'Green');
}

class ShowSnackBrown extends ReCounterAction {
  const ShowSnackBrown() : super(Colors.brown, 'Brown - Reseting');
}

abstract class ReCounterEvent {}

class ResetCounter extends ReCounterEvent {}

class IncrementCounter extends ReCounterEvent {}

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

1 回复

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


当然,re_state_action 是一个用于 Flutter 状态管理和动作触发的插件,它可以帮助开发者更高效地管理应用状态。以下是一个基本的代码案例,展示了如何在 Flutter 应用中使用 re_state_action 插件。

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

dependencies:
  flutter:
    sdk: flutter
  re_state_action: ^最新版本号  # 请替换为实际的最新版本号

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

接下来是一个简单的 Flutter 应用示例,展示了如何使用 re_state_action 插件进行状态管理和动作触发。

main.dart

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter State Management with re_state_action',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> with ReStateActionMixin {
  // 定义状态变量
  int counter = 0;

  // 定义动作
  void incrementCounter() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter State Management'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 触发动作
          incrementCounter();
          // 也可以通过插件提供的接口触发动作(假设插件提供了这样的功能)
          // this.triggerAction("incrementCounter");
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

// 假设插件提供了全局状态管理功能(此部分仅为示例,具体实现需参考插件文档)
// class GlobalState {
//   static int globalCounter = 0;
//
//   static void incrementGlobalCounter() {
//     globalCounter++;
//   }
// }

// // 在某处使用全局状态管理(此部分仅为示例,具体实现需参考插件文档)
// // GlobalState.incrementGlobalCounter();

请注意,上述代码示例主要展示了如何在 Flutter 应用中使用标准的 setState 方法进行状态管理。由于 re_state_action 插件的具体功能和 API 可能会有所不同,因此你可能需要参考插件的官方文档来了解更多关于全局状态管理、动作触发等高级功能。

如果 re_state_action 插件提供了全局状态管理或动作触发的高级功能,你通常会看到类似这样的代码片段(假设插件的 API 是这样的):

// 初始化全局状态管理
ReStateAction.initialize();

// 在某处触发动作
ReStateAction.triggerAction("incrementCounter");

// 监听动作
ReStateAction.addActionListener("incrementCounter", () {
  // 处理动作的逻辑
  setState(() {
    counter++;
  });
});

但请注意,上述假设的 API 并不是 re_state_action 插件的实际 API。为了获得准确的代码示例和 API 使用方法,请务必参考 re_state_action 插件的官方文档和示例代码。

回到顶部