Flutter状态共享插件value_notifier_plus的使用

Flutter状态共享插件value_notifier_plus的使用

ValueNotifierPlus 是一个扩展了 Flutter 中 ValueNotifier 功能的包,提供了使用 ValueNotifier 替代 Streams 的一种方式。ValueNotifier 在性能方面更高效,因为它不需要处理复杂的异步流系统。这在需要高频更新用户界面的场景中尤为重要。

安装

在你的 pubspec.yaml 文件中添加 ValueNotifierPlus

dependencies:
  value_notifier_plus: x.x.x

什么是 ValueNotifierPlus

ValueNotifierPlus 是一个扩展了 Flutter 中标准 ValueNotifier 的类,它添加了不可变状态的能力,并简化了与小部件树的集成。它使得状态管理更加高效且简洁,无需使用复杂的流和事件。

ValueNotifierPlus 小部件

BuilderPlus

BuilderPlus 是一个当 ValueNotifierPlus 的值发生变化时会重建其小部件树的小部件。它类似于 flutter_bloc 包中的 BlocBuilder

使用示例
import 'package:flutter/material.dart';
import 'value_notifier_plus.dart';

class CounterNotifier extends ValueNotifierPlus<int> {
  CounterNotifier() : super(0);

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return PlusProvider(
      provider: CounterNotifier(),
      child: MaterialApp(
        home: CounterPage(),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterNotifier = context.of<CounterNotifier>();

    return Scaffold(
      appBar: AppBar(title: Text('ValueNotifierPlus Example')),
      body: Center(
        child: BuilderPlus<CounterNotifier, int>(
          notifier: counterNotifier,
          builder: (context, state) {
            return Text('Counter: $state');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: counterNotifier.increment,
        child: Icon(Icons.add),
      ),
    );
  }
}

ListenerPlus

ListenerPlus 是一个当 ValueNotifierPlus 的值发生变化时会执行特定函数的小部件,而不会重建整个小部件树。它类似于 flutter_bloc 包中的 BlocListener

使用示例
import 'package:flutter/material.dart';
import 'value_notifier_plus.dart';

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterNotifier = context.of<CounterNotifier>();

    return Scaffold(
      appBar: AppBar(title: Text('ValueNotifierPlus Example')),
      body: Center(
        child: ListenerPlus<CounterNotifier, int>(
          notifier: counterNotifier,
          listener: (context, state) {
            if (state == 10) {
              ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Reached 10!')));
            }
          },
          child: ListenerPlus<CounterNotifier, int>(
            notifier: counterNotifier,
            builder: (context, state) {
              return Text('Counter: $state');
            },
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          counterNotifier.increment();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

ConsumerPlus

ConsumerPlus 结合了 ValueNotifierPlusListenerValueNotifierPlusBuilder 的功能,允许监听并响应状态变化来重建小部件树。它类似于 flutter_bloc 包中的 BlocConsumer

使用示例
import 'package:flutter/material.dart';
import 'value_notifier_plus.dart';

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterNotifier = context.of<CounterNotifier>();

    return Scaffold(
      appBar: AppBar(title: Text('ValueNotifierPlus Example')),
      body: Center(
        child: ConsumerPlus<CounterNotifier, int>(
          notifier: counterNotifier,
          listener: (context, state) {
            if (state == 10) {
              ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Reached 10!')));
            }
          },
          builder: (context, state) {
            return Text('Counter: $state');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          counterNotifier.increment();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

ListenersPlus 和 ProvidersPlus

ListenersPlusProvidersPlus 允许同时注册多个监听器和提供者到不同的 ValueNotifierPlus,从而简化多观察者的代码。它类似于 flutter_bloc 包中的 MultiBlocListenerMultiBlocProvider

使用示例
import 'package:flutter/material.dart';
import 'value_notifier_plus.dart';

class CounterNotifier extends ValueNotifierPlus<int> {
  CounterNotifier() : super(0);

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

class AnotherNotifier extends ValueNotifierPlus<int> {
  AnotherNotifier() : super(0);

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ProvidersPlus(
      providers: [
        CounterNotifier(),
        AnotherNotifier(),
      ],
      child: Builder(
        builder: (context) {
          return const MaterialApp(
            home: CounterPage(),
          );
        },
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterNotifier = context.of<CounterNotifier>();
    final anotherNotifier = context.of<AnotherNotifier>();

    return Scaffold(
      appBar: AppBar(title: Text('ValueNotifierPlus Example')),
      body: Center(
        child: ListenersPlus(
          listeners: [
            ListenerPlus<CounterNotifier, int>(
              notifier: counterNotifier,
              listener: (context, state) {
                if (state == 5) {
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Counter Reached 5!')));
                }
              },
              child: Container(),
            ),
            ListenerPlus<AnotherNotifier, int>(
              notifier: anotherNotifier,
              listener: (context, state) {
                if (state == 10) {
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('AnotherNotifier Reached 10!')));
                }
              },
              child: Container(),
            ),
          ],
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              BuilderPlus<CounterNotifier, int>(
                notifier: counterNotifier,
                builder: (context, state) {
                  return Text('Counter: $state');
                },
              ),
              BuilderPlus<AnotherNotifier, int>(
                notifier: anotherNotifier,
                builder: (context, state) {
                  return Text('AnotherNotifier: $state');
                },
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          counterNotifier.increment();
          anotherNotifier.increment();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

观察者

你可以添加一个观察者来监控 ValueNotifierPlus 的状态变化:

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

class MyObserver extends ObserverPlus {
  @override
  void onChange<ValueNotifierPlusType extends ValueNotifierPlus>(
    ValueNotifierPlusType notifier,
    Object? state,
  ) {
    print('State changed to $state');
  }
}

void main() {
  ValueNotifierPlus.observer = MyObserver();
  runApp(MyApp());
}

测试

要运行测试,请在终端中执行以下命令:

flutter test

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

1 回复

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


value_notifier_plus 是一个 Flutter 插件,它扩展了 Flutter 内置的 ValueNotifier 类,提供了更多功能和便利性,使得在 Flutter 应用中管理和共享状态更加简单。它类似于 ProviderRiverpod,但更轻量级且专注于 ValueNotifier

以下是 value_notifier_plus 的基本使用方法和示例:

1. 安装插件

pubspec.yaml 中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  value_notifier_plus: ^1.0.0

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

2. 创建状态管理类

使用 ValueNotifierPlus 包裹你的状态。例如,管理一个计数器的状态:

import 'package:value_notifier_plus/value_notifier_plus.dart';

class Counter with ValueNotifierPlus<int> {
  Counter() : super(0); // 初始值为 0

  void increment() {
    value++; // 更新值
  }

  void decrement() {
    value--; // 更新值
  }
}

3. 在 UI 中使用状态

在 Flutter 应用中使用 ValueNotifierPlus 提供的 ValueListenableBuilderwatch 方法来监听状态变化并更新 UI。

import 'package:flutter/material.dart';
import 'counter.dart'; // 导入上面的 Counter 类

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ValueNotifierPlus Example')),
        body: CounterProvider(
          child: CounterScreen(),
        ),
      ),
    );
  }
}

class CounterProvider extends InheritedWidget {
  final Counter counter = Counter();

  CounterProvider({required Widget child}) : super(child: child);

  static Counter of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<CounterProvider>()!.counter;
  }

  [@override](/user/override)
  bool updateShouldNotify(CounterProvider oldWidget) => false;
}

class CounterScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final counter = CounterProvider.of(context);

    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ValueListenableBuilder<int>(
            valueListenable: counter,
            builder: (context, value, child) {
              return Text('Count: $value', style: TextStyle(fontSize: 24));
            },
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: counter.increment,
            child: Text('Increment'),
          ),
          ElevatedButton(
            onPressed: counter.decrement,
            child: Text('Decrement'),
          ),
        ],
      ),
    );
  }
}
回到顶部