Flutter信息通知插件informers的使用

Flutter信息通知插件informers的使用

这是一个简单的包,复制并修改了Flutter的ValueNotifier的行为。主要的区别在于,这个包中的通知器允许在值为iterables(如mapslists)时更容易进行更新。

未来的发展方向围绕着改进所有通知器以模仿默认可迭代对象的行为,并同时尽可能高效地更新监听器。如果您有任何想法或希望看到任何特定的方法/类,请随时提出请求或提交PR。

通用

每种类型的通知器(InformerListInformerMapInformer)都有以下三个变量和一个重建方法:

  • _value / value → 当前的通知器值。
  • _forceUpdate → 是否始终重建。
/// 表示通知器是否应该在调用`update`和`updateCurrent`方法时始终更新值并通知监听器。
///
/// 即使值可能相同。
final bool _forceUpdate;
  • rebuild() ⇒ 暴露的notifyListeners方法,用于手动触发重建。
/// 用于强制通知此超级`ChangeNotifier`的监听器。
void rebuild() => notifyListeners();

Informer

1.jpg

除了通用方法外,主Informer类还有以下方法:

/// 标准值设置器,尊重_forceUpdate标志
set value(T newValue) => update(newValue);

/// 在不通知监听器的情况下更新值
void silentUpdate(T value) => update(value, doNotifyListeners: false);

/// 设置通知器的当前值。
void update(T value, {bool doNotifyListeners = true}) {
  if (_forceUpdate || _value != value) {
    _value = value;
    if (doNotifyListeners) {
      notifyListeners();
    }
  }
}

/// 提供当前值并使用接收到的值更新它。
void updateCurrent(T Function(T value) current, {bool doNotifyListeners = true}) {
  final newValue = current(_value);
  if (_forceUpdate || _value != newValue) {
    _value = newValue;
    if (doNotifyListeners) {
      notifyListeners();
    }
  }
}
informer.jpg

ListInformer

3.jpg

除了通用方法外,ListInformer类还有以下方法:

/// 设置通知器的当前列表。
void update(List<T> value) {
  if (_forceUpdate || _value != value) {
    _value = value;
    notifyListeners();
  }
}

/// 提供当前列表并使用接收到的列表更新通知器的列表。
void updateCurrent(List<T> Function(List<T> current) current) {
  final newValue = current(_value);
  if (_forceUpdate || _value != newValue) {
    _value = newValue;
    notifyListeners();
  }
}

/// 向列表添加一个值。
void add(T value) {
  _value.add(value);
  notifyListeners();
}

/// 从列表中移除一个值。
bool remove(T value) {
  final _result = _value.remove(value);
  notifyListeners();
  return _result;
}

/// 移除列表的最后一个值。
T removeLast() {
  final _removed = _value.removeLast();
  notifyListeners();
  return _removed;
}

/// 更新第一个满足条件的值。
T? updateFirstWhereOrNull(
  bool Function(T value) test,
  T Function(T value) update,
) {
  int? _index;
  T? toBeUpdated;
  for (int index = 0; index < _value.length; index++) {
    final value = _value[index];
    if (test(value)) {
      _index = index;
      toBeUpdated = value;
    }
  }
  if (toBeUpdated != null) {
    final updated = update(toBeUpdated);
    _value[_index!] = updated;
    notifyListeners();
    return updated;
  }
  return null;
}

/// 列表是否为空。
bool get isEmpty => _value.isEmpty;

/// 列表是否非空。
bool get isNotEmpty => _value.isNotEmpty;

/// 列表是否包含值。
bool contains(T value) => _value.contains(value);

/// 清空列表中的任何值。
void clear() {
  _value.clear();
  notifyListeners();
}
listinformer.jpg

MapInformer

2.jpg

除了通用方法外,MapInformer类还有以下方法:

/// 设置通知器的当前映射。
void update(Map<E, T> value) {
  if (_forceUpdate || _value != value) {
    _value = value;
    notifyListeners();
  }
}

/// 提供当前映射并使用接收到的映射更新通知器的映射。
void updateCurrent(Map<E, T> Function(Map<E, T> current) current) {
  final newValue = current(_value);
  if (_forceUpdate || _value != newValue) {
    _value = newValue;
    notifyListeners();
  }
}

/// 使用给定的[key]调用[Map.update]方法更新值。
void updateKey(E key, T Function(T value) update, {T Function()? ifAbsent}) {
  _value = _value..update(key, update, ifAbsent: ifAbsent);
  notifyListeners();
}

/// 将[value]分配给[key]。
void add(E key, T value) {
  _value[key] = value;
  notifyListeners();
}

/// 从[_value]中移除[key]。
T? remove(E key) {
  final removed = _value.remove(key);
  notifyListeners();
  return removed;
}

/// 执行[Map.putIfAbsent]并返回其返回值。
T putIfAbsent(E key, T value) {
  final _returnValue = _value.putIfAbsent(key, () => value);
  notifyListeners();
  return _returnValue;
}

/// 清空映射中的任何值。
void clear() {
  _value.clear();
  notifyListeners();
}
mapinformer.jpg

示例代码

example/lib/main.dart

import 'dart:math';

import 'package:example/widgets/example_implementations/informer_example.dart';
import 'package:example/widgets/example_implementations/list_informer_example.dart';
import 'package:example/widgets/example_implementations/map_informer_example.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:informers/informer.dart';
import 'package:informers/list_informer.dart';
import 'package:informers/map_informer.dart';
import 'package:veto/data/models/base_view_model.dart';

import 'data/constants/const_values.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Informers',
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: const HomeView(),
    );
  }
}

class HomeView extends StatelessWidget {
  const HomeView({Key? key}) : super(key: key);
  static const String route = 'home-view';

  [@override](/user/override)
  Widget build(BuildContext context) => ViewModelBuilder<HomeViewModel>(
        builder: (context, model) {
          return GestureDetector(
            onTap: model.focusNode.unfocus,
            child: Scaffold(
              appBar: AppBar(
                title: const Text('Informers Example Project'),
              ),
              body: SingleChildScrollView(
                child: Column(
                  children: [
                    const SizedBox(height: 16),
                    InformerExample(model: model),
                    ListInformerExample(model: model),
                    MapInformerExample(model: model),
                    const SizedBox(height: kBottomNavigationBarHeight),
                  ],
                ),
              ),
            ),
          );
        },
        viewModelBuilder: () => HomeViewModel.locate,
      );
}

class HomeViewModel extends BaseViewModel {
  final Informer<int> _counter = Informer(0);
  ValueListenable<int> get counterListenable => _counter;

  final ListInformer<String> _listItems = ListInformer([]);
  ValueListenable<List<String>> get listItemsListenable => _listItems;

  final MapInformer<String, String> _mapItems = MapInformer({});
  ValueListenable<Map<String, String>> get mapItemsListenable => _mapItems;

  late final random = Random();

  [@override](/user/override)
  Future<void> initialise() async {
    super.initialise();
  }

  [@override](/user/override)
  void dispose() {
    _counter.dispose();
    _listItems.dispose();
    super.dispose();
  }

  // -------- Informer ---- Informer ---- Informer -------- \\
  
  void updateCounter({required int value}) => _counter.update(value);

  void decrementCounter() => _counter.updateCurrent((value) => --value);

  void incrementCounter() => _counter.updateCurrent((value) => ++value);

  // -------- ListInformer ---- ListInformer ---- ListInformer -------- \\

  void updateListItems({required List<String> values}) => _listItems.update(values);

  void decrementListItems() => _listItems.updateCurrent((value) => value..removeLast());

  void incrementListItems() => _listItems.updateCurrent((value) => value..add(_randomGangstaLoremIpsum));

  void addListItem({required String value}) => _listItems.add(value);

  bool removeListItem({required String value}) {
    if (_listItems.contains(value)) {
      _listItems.remove(value);
      return true;
    }
    return false;
  }

  void removeLastListItem() {
    if (_listItems.isNotEmpty) {
      _listItems.removeLast();
    }
  }

  bool updateFirstWhereOrNull({
    required String testValue,
    required String updateValue,
  }) => _listItems.updateFirstWhereOrNull(
    (value) => value == testValue,
    (_) => updateValue,
  ) != null;

  // -------- MapInformer ---- MapInformer ---- MapInformer -------- \\

  void addMapItem({required String key, required String value}) => _mapItems.add(key, value);

  bool removeMapItem({required String key}) => _mapItems.remove(key) != null;

  void updateMapItems({required Map<String, String> values}) => _mapItems.update(values);

  void updateMapItemsKey({required String key, required String value}) => _mapItems.updateKey(key, (_) => value, ifAbsent: () => value);

  void decrementMapItems() => _mapItems.updateCurrent(
        (current) => current..remove(_mapItems.value.keys.last),
      );

  void incrementMapItems() {
    _mapItems.updateCurrent((current) =>
        current..[_randomGangstaLoremIpsum] = _randomGangstaLoremIpsum);
  }

  String putIfAbsent({required String key, required String value}) => _mapItems.putIfAbsent(key, value);

  // -------- UTIL ---- UTIL ---- UTIL -------- \\

  String get _randomGangstaLoremIpsum => ConstValues.randomGangstaLoremIpsum[random.nextInt(
        ConstValues.randomGangstaLoremIpsum.length,
      )];

  TextStyle get exampleTitleStyle => Theme.of(context).textTheme.bodyText1!.copyWith(
        fontSize: 20,
        fontWeight: FontWeight.bold,
      );

  static HomeViewModel get locate => HomeViewModel();
}

更多关于Flutter信息通知插件informers的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter信息通知插件informers的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,informers 是一个用于管理和显示信息通知的插件。它可以帮助你轻松地在应用中显示各种通知,如成功、错误、警告等。以下是使用 informers 插件的基本步骤。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  informers: ^1.0.0  # 请根据实际情况使用最新版本

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

2. 导入插件

在你的 Dart 文件中导入 informers 插件:

import 'package:informers/informers.dart';

3. 使用 Informer

informers 插件提供了多种类型的通知,你可以根据需要使用不同的方法。

显示简单通知

Informer.show(
  context,
  InformerType.success,
  message: '操作成功!',
);

显示错误通知

Informer.show(
  context,
  InformerType.error,
  message: '发生了一个错误!',
);

显示警告通知

Informer.show(
  context,
  InformerType.warning,
  message: '请注意!',
);

显示自定义通知

你可以自定义通知的样式和持续时间:

Informer.show(
  context,
  InformerType.info,
  message: '这是一条自定义通知',
  duration: Duration(seconds: 5),
  style: InformerStyle(
    backgroundColor: Colors.blue,
    textColor: Colors.white,
  ),
);

4. 自定义 Informer

你可以通过 InformerStyle 来自定义通知的外观:

InformerStyle(
  backgroundColor: Colors.green,
  textColor: Colors.white,
  icon: Icons.check_circle,
  borderRadius: BorderRadius.circular(10),
  padding: EdgeInsets.all(16),
  margin: EdgeInsets.all(10),
);

5. 全局配置

你可以在应用的入口处全局配置 Informer 的默认样式和行为:

void main() {
  InformerConfig(
    defaultDuration: Duration(seconds: 3),
    defaultStyle: InformerStyle(
      backgroundColor: Colors.blue,
      textColor: Colors.white,
    ),
  );

  runApp(MyApp());
}

6. 示例代码

以下是一个完整的示例代码,展示了如何使用 informers 插件:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Informers Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {
                  Informer.show(
                    context,
                    InformerType.success,
                    message: '操作成功!',
                  );
                },
                child: Text('显示成功通知'),
              ),
              ElevatedButton(
                onPressed: () {
                  Informer.show(
                    context,
                    InformerType.error,
                    message: '发生了一个错误!',
                  );
                },
                child: Text('显示错误通知'),
              ),
              ElevatedButton(
                onPressed: () {
                  Informer.show(
                    context,
                    InformerType.warning,
                    message: '请注意!',
                  );
                },
                child: Text('显示警告通知'),
              ),
              ElevatedButton(
                onPressed: () {
                  Informer.show(
                    context,
                    InformerType.info,
                    message: '这是一条自定义通知',
                    duration: Duration(seconds: 5),
                    style: InformerStyle(
                      backgroundColor: Colors.blue,
                      textColor: Colors.white,
                    ),
                  );
                },
                child: Text('显示自定义通知'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
回到顶部