Flutter异步通知插件async_notifier的使用
Flutter异步通知插件async_notifier的使用
AsyncNotifier 是一个用于处理所有异步状态的 ValueNotifier。它允许监听、通知并管理加载、错误和数据状态,所有这些都集中在一个地方。
使用方法
AsyncNotifier 实质上是一个带有两个新设置器 future 和 stream 的 ValueNotifier。它的所有状态都被解析为一个 AsyncSnapshot。由于其特性,它可以很容易地与Flutter的原生小部件和类集成,使得使用起来简单直接。
简单示例
import 'package:async_notifier/async_notifier.dart';
void main() {
  // 不需要初始值,默认为 AsyncSnapshot.nothing()
  final counter = AsyncNotifier<int>();
  // 可监听
  counter.addListener(() {
    print("New state: ${counter.snapshot}");
  });
  // 设置 future 或 stream
  counter.future = Future.value(42);
  counter.stream = Stream.fromIterable([1, 2, 3]);
  // 获取快照
  final AsyncSnapshot<int> snapshot = counter.snapshot;
  // 使用扩展检查状态
  snapshot.isLoading;
  snapshot.isReloading;
  snapshot.requireData;
  snapshot.hasData;
  snapshot.hasError;
  snapshot.hasNone;
  snapshot.error;
  snapshot.stackTrace;
  // 控制 future 或 stream
  counter.cancel(); // 对 future 有效
  counter.dispose();
  // 解析状态
  final result = counter.when(
    data: (data) => 'Data $data',
    error: (error, stackTrace) => 'Error $error',
    loading: () => 'Loading',
  );
  // 或者使用 switch 表达式
  final resultSwitch = switch (snapshot) {
    AsyncSnapshot(:var data?) => 'Data $data',
    AsyncSnapshot(:var error?) => 'Error $error', 
    _ => 'Loading',
  };
}
状态管理
你可以直接监听所有 AsyncNotifier 状态,并将其绑定到其他对象。
class TodosNotifier extends ChangeNotifier {
  TodosNotifier() {
    _todos.addListener(notifyListeners);
    fetchTodos();
  }
  final _todos = AsyncNotifier<List<Todo>>();
  AsyncSnapshot<List<Todo>> get todosSnapshot => _todos.snapshot;
  void fetchTodos() {
    _todos.future = _repository.fetchTodos();
  }
  [@override](/user/override)
  void dispose() {
    _todos.dispose();
    super.dispose();
  }
}
消费状态
你可以使用Flutter的原生解决方案如 ListenableBuilder 来消费状态。
class TodoList extends StatelessWidget {
  const TodoList({super.key, required this.todosNotifier});
  final TodosNotifier todosNotifier;
  [@override](/user/override)
  Widget build(BuildContext context) {
    return ListenableBuilder(
      listenable: todosNotifier,
      builder: (context, _) {
        return todosNotifier.snapshot.when(
          loading: () => const CircularProgressIndicator(),
          error: (error, stackTrace) => Text('Error: $error'),
          data: (data) => ListView.builder(
            itemCount: data.length,
            itemBuilder: (context, index) => Text(data[index].title),
          ),
        );
      },
    );
  }
}
使用 provider:
class TodoList extends StatelessWidget {
  const TodoList({super.key});
  [@override](/user/override)
  Widget build(BuildContext context) {
    final todosSnapshot = context.watch<TodosNotifier>().snapshot;
    return todosSnapshot.when(
      loading: () => const CircularProgressIndicator(),
      error: (error, stackTrace) => Text('Error: $error'),
      data: (data) => ListView.builder(
        itemCount: todosListenable.value.length,
        itemBuilder: (context, index) => Text(data[index].title),
      ),
    );
  }
}
完整示例 Demo
以下是一个完整的示例,展示了如何使用 AsyncNotifier 来管理书籍列表的状态,并在UI中显示加载、错误和数据状态。
import 'dart:async';
import 'package:async_notifier/async_notifier.dart';
import 'package:flutter/material.dart';
void main() {
  runApp(MainApp(notifier: TodosNotifier()));
}
class Book {
  const Book({required this.id, required this.title});
  final String title;
  final int id;
  [@override](/user/override)
  operator ==(Object other) => other is Book && other.id == id;
  [@override](/user/override)
  int get hashCode => id.hashCode;
}
class BookRepository {
  static final _books = {
    const Book(id: 0, title: 'The Book of Spells'),
    const Book(id: 1, title: 'The Darkhold'),
    const Book(id: 2, title: "The Hitchhiker's Guide to the Galaxy"),
    const Book(id: 3, title: 'The Dark Note'),
    const Book(id: 4, title: 'Book of Cagliostro'),
    const Book(id: 5, title: 'Tome of Stilled Tongue'),
  };
  Future<void> saveBooks(List<Book> books) async {
    await Future<void>.delayed(const Duration(seconds: 1));
    _books.clear();
    _books.addAll(books);
  }
  Stream<List<Book>> streamBooks() async* {
    await Future<void>.delayed(const Duration(seconds: 1));
    yield _books.toList();
  }
  Future<List<Book>> getBooks() async {
    await Future<void>.delayed(const Duration(seconds: 1));
    return _books.toList();
  }
}
class TodosNotifier extends ChangeNotifier {
  TodosNotifier() {
    _books.addListener(notifyListeners);
  }
  final _repository = BookRepository();
  final _books = AsyncNotifier<List<Book>>();
  AsyncSnapshot<List<Book>> get snapshot => _books.snapshot
      .whenData((list) => isAscending ? list : list.reversed.toList());
  bool get isAscending => _ascending;
  var _ascending = false;
  StreamSubscription<List<Book>>? _booksSubscription;
  void toggleSort() {
    _ascending = !_ascending;
    notifyListeners();
  }
  void fetchBooks() {
    _books.future = _repository.getBooks();
  }
  void streamBooks() {
    _booksSubscription = _repository.streamBooks().listen(setBooks);
  }
  void setBooks(List<Book> books) {
    _books.future = Future.value(books);
  }
  void addBook(Book book) {
    fetchBooks();
  }
  void removeBook(Book book) {}
  [@override](/user/override)
  void dispose() {
    _books.dispose();
    _booksSubscription?.cancel();
    super.dispose();
  }
}
class MainApp extends StatelessWidget {
  const MainApp({super.key, required this.notifier});
  final TodosNotifier notifier;
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('AsyncNotifier'),
          actions: [
            IconButton(
              icon: const Icon(Icons.refresh),
              onPressed: notifier.fetchBooks,
            ),
            IconButton(
              icon: const Icon(Icons.sort),
              onPressed: () => notifier.toggleSort(),
            ),
          ],
        ),
        body: Center(
          child: RefreshIndicator(
            onRefresh: () async => notifier.fetchBooks(),
            child: ListenableBuilder(
              listenable: notifier,
              builder: (context, _) {
                final list = notifier.snapshot.data ?? [];
                if (notifier.snapshot.isLoading) {
                  return const CircularProgressIndicator();
                }
                return ListView.builder(
                  itemCount: list.length,
                  itemBuilder: (context, index) {
                    final book = list[index];
                    return ListTile(
                      title: Text(book.title),
                      trailing: IconButton(
                        icon: const Icon(Icons.delete),
                        onPressed: () => notifier.removeBook(book),
                      ),
                    );
                  },
                );
              },
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            notifier.addBook(
              const Book(id: 7, title: 'The 7 Wonders'),
            );
          },
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}
更多关于Flutter异步通知插件async_notifier的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter异步通知插件async_notifier的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用async_notifier插件来实现异步通知的示例代码。async_notifier插件通常用于在后台任务完成时向UI发送通知。
首先,确保你已经在pubspec.yaml文件中添加了async_notifier依赖:
dependencies:
  flutter:
    sdk: flutter
  async_notifier: ^x.y.z  # 请替换为最新版本号
然后,运行flutter pub get来安装依赖。
接下来,我们编写一个简单的Flutter应用,展示如何使用async_notifier。
1. 创建一个通知服务
首先,我们创建一个服务类,用于处理异步任务并发送通知。
import 'package:async_notifier/async_notifier.dart';
import 'dart:async';
class NotificationService {
  final AsyncNotifier<String> notifier = AsyncNotifier<String>();
  Future<void> performAsyncTask() async {
    // 模拟一个耗时任务
    await Future.delayed(Duration(seconds: 3));
    // 任务完成后发送通知
    notifier.notify("Task completed!");
  }
}
2. 在UI中使用通知服务
接下来,我们在UI组件中使用这个服务,并监听通知。
import 'package:flutter/material.dart';
import 'package:async_notifier/async_notifier.dart';
import 'notification_service.dart';  // 假设你将上面的代码保存在这个文件里
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: NotificationScreen(),
    );
  }
}
class NotificationScreen extends StatefulWidget {
  @override
  _NotificationScreenState createState() => _NotificationScreenState();
}
class _NotificationScreenState extends State<NotificationScreen> {
  final NotificationService _notificationService = NotificationService();
  String _notificationMessage = "";
  @override
  void initState() {
    super.initState();
    // 订阅通知
    _notificationService.notifier.subscribe((message) {
      setState(() {
        _notificationMessage = message;
      });
    });
    // 启动异步任务
    _notificationService.performAsyncTask();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Async Notifier Example"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              "Notification Message:",
              style: TextStyle(fontSize: 18),
            ),
            SizedBox(height: 10),
            Text(
              _notificationMessage,
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
          ],
        ),
      ),
    );
  }
}
3. 运行应用
现在,你可以运行这个Flutter应用。当应用启动时,它会启动一个异步任务,并在任务完成后更新UI,显示“Task completed!”消息。
这个示例展示了如何使用async_notifier插件来在Flutter应用中处理异步通知。你可以根据需要扩展这个示例,以处理更复杂的异步任务和通知逻辑。
 
        
       
             
             
            

