Flutter轻量级状态管理插件ministate的使用

Flutter轻量级状态管理插件ministate的使用

特性

简单的状态管理基于:

  • 服务定位模式(Service Locator Pattern)使用 GetIt
  • 自定义状态类使用 ValueNotifier
  • 自定义 MiniStateBuilder 基于 ValueListenableBuilder

开始使用

创建一些状态类

状态类将持有应用程序的部分或全部状态。为了区分新旧状态,确保状态可以进行比较。

class SomeState extends Equatable {
  final int counter;

  const SomeState(this.counter);
  [@override](/user/override)
  List<Object?> get props => [counter];
}

定义一个状态持有者和服务

为了分离逻辑、状态和持久化,每个状态将由一个状态持有者类处理,该类知道使用哪个服务进行持久化。

首先定义一个服务类。这是与后端服务通信或在设备上进行本地持久化的场所。

class BackendService {
  void saveState(SomeState state) {
    // 魔法般地保存状态到某个存储
  }

  Future<SomeState> retrieveLastState() async {
    // 可能会保存到sqlite或firebase
    return const SomeState(0);
  }
}

然后定义一个状态持有者类,将所有内容绑定在一起。状态持有者类继承自 DefaultStateHolder 并且类型为 StateClassService 类名。

状态持有者类的功能:

  1. 持有状态
  2. 提供可以在任何地方使用的变更方法
  3. 知道如何通知渲染小部件的变化
class CounterStateHolder extends DefaultStateHolder<SomeState, BackendService> {
  CounterStateHolder(SomeState value) : super(value);

  // 定义变更方法
  void increment() {
    // 创建新的状态,从旧值/状态派生
    var nextState = SomeState(value.counter + 1);
    // 使用 backendService 将状态保存到某处
    getService().saveState(nextState);
    // 调用 setState 触发重新渲染
    setState(nextState);
  }

  void decrement() {
    // 创建新的状态,从旧值/状态派生
    // 调用 setState 触发重新渲染
    setState(SomeState(value.counter - 1));
  }
}

使用

一旦所有必要的类都设置好了,确保在应用程序启动前注册所有的 StateHolder 及其 Services

void main() {
  // 在应用程序启动前注册所有状态持有者及其所需的服务
  registerState(CounterStateHolder(const SomeState(0)), BackendService());
  // 最后运行应用程序
  runApp(const MyApp());
}

要显示状态并响应状态变化,使用:

// 在代码中的任何位置访问状态持有者
var stateholder = stateHolder<CounterStateHolder>();
...
MiniStateBuilder<CounterStateHolder, SomeState>(
  listener: (context, value) {
    // 在渲染新状态之前在此处对特定状态作出反应
    if (value.counter == 10) {
      // 通过显式设置状态值来重置
      stateholder.setState(const SomeState(0));
    }
  },
  builder: (ctx, value, stateHolder, child) {
    return Text(
      '${value.counter}',
      style: Theme.of(context).textTheme.headline4,
    );
  }
)
...

由于状态持有者可以通过服务定位模式在任何地方使用,因此可以直接在任何操作处理器中使用它来变更状态。

ElevatedButton(
  onPressed: () {
    stateHolder<CounterStateHolder>().decrement();
  },
  child: const Text("-"),
),

示例代码

以下是完整的示例代码:

import 'dart:developer';

import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:ministate/ministate.dart';

// 创建一些状态
class SomeState extends Equatable {
  final int counter;

  const SomeState(this.counter);
  [@override](/user/override)
  List<Object?> get props => [counter];
}

// 一些作为服务使用的类
class BackendService {
  void saveState(SomeState state) {
    // 魔法般地保存状态到某个存储
  }

  Future<SomeState> retrieveLastState() async {
    return const SomeState(0);
  }
}

// 定义状态持有者并从 GetItStateHolder 继承
class CounterStateHolder extends DefaultStateHolder<SomeState, BackendService> {
  CounterStateHolder(SomeState value) : super(value);

  // 定义变更方法
  void increment() {
    // 创建新的状态,从旧值/状态派生
    // 调用 setState 触发重新渲染
    var nextState = SomeState(value.counter + 1);
    // 使用 backendService 将状态保存到某处
    getService().saveState(nextState);
    setState(nextState);
  }

  void decrement() {
    // 创建新的状态,从旧值/状态派生
    // 调用 setState 触发重新渲染
    setState(SomeState(value.counter - 1));
  }
}

void main() {
  // 在应用程序启动前注册所有状态持有者及其所需的服务
  registerState(CounterStateHolder(const SomeState(0)), BackendService());
  // 最后运行应用程序
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Minimalist State Management'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String title;

  const MyHomePage({Key? key, required this.title}) : super(key: key);

  void _incrementCounter() {
    // 自由访问状态持有者,使用 GetIt 定位器
    stateHolder<CounterStateHolder>().increment();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    var stateholder = stateHolder<CounterStateHolder>();
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            // 确保状态更改时触发重新渲染
            // 通过使用 MiniStateBuilder
            MiniStateBuilder<CounterStateHolder, SomeState>(
              listener: (context, value) {
                // 在渲染新状态之前在此处对特定状态作出反应
                if (value.counter == 10) {
                  // 通过显式设置状态值来重置
                  stateholder.setState(const SomeState(0));
                }
              },
              builder: (ctx, value, stateHolder, child) {
                return Text(
                  '${value.counter}',
                  style: Theme.of(context).textTheme.headline4,
                );
              }
            )
          ],
        ),
      ),
      persistentFooterButtons: [
        ElevatedButton(
          onPressed: () {
            stateholder.decrement();
          },
          child: const Text("-"),
        ),
        ElevatedButton(
          onPressed: () {
            stateholder.increment();
          },
          child: const Text("+"),
        ),
      ],
    );
  }
}

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

1 回复

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


mini_state 是一个轻量级的状态管理插件,适用于 Flutter 应用。它提供了一种简单的方式来管理应用的状态,并且不需要引入复杂的状态管理框架如 ProviderBlocRiverpodmini_state 的核心思想是将状态管理与 UI 分离,使得代码更加简洁、易于维护。

以下是 mini_state 的基本使用方法:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 mini_state 依赖:

dependencies:
  flutter:
    sdk: flutter
  mini_state: ^0.1.0

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

2. 创建一个状态类

创建一个状态类,它将包含你应用中需要管理的数据。你可以使用 MiniState 类来扩展你的状态类。

import 'package:mini_state/mini_state.dart';

class CounterState extends MiniState {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners(); // 通知监听器状态已经改变
  }
}

3. 在 UI 中使用状态

在你的 UI 中,使用 MiniStateProvider 来提供状态,并使用 MiniStateConsumer 来监听状态的变化。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MiniStateProvider(
      create: (context) => CounterState(),
      child: MaterialApp(
        home: HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MiniState Example'),
      ),
      body: Center(
        child: MiniStateConsumer<CounterState>(
          builder: (context, state) {
            return Text(
              'Count: ${state.count}',
              style: TextStyle(fontSize: 24),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 获取状态并调用方法
          MiniStateProvider.of<CounterState>(context).increment();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

4. 运行应用

现在你可以运行应用,点击浮动按钮会看到计数器增加,并且 UI 会自动更新。

5. 其他功能

mini_state 还提供了一些其他功能,比如 MiniStateSelector,它允许你只监听状态的一部分,以减少不必要的重建。

MiniStateSelector<CounterState, int>(
  selector: (state) => state.count,
  builder: (context, count) {
    return Text(
      'Count: $count',
      style: TextStyle(fontSize: 24),
    );
  },
)
回到顶部