Flutter 数据监听器ChangeNotifier
Posted 伟雪无痕
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 数据监听器ChangeNotifier相关的知识,希望对你有一定的参考价值。
一.ChangeNotifier的简单介绍
ChangeNotifier是 Flutter SDK 中的一个简单的类。它用于向监听器发送通知。换言之,如果被定义为 ChangeNotifier,你可以订阅它的状态变化。(这和大家所熟悉的观察者模式相类似),了解更多请参考ChangeNotifier class - foundation library - Dart API
二.ChangeNotifier源码分析
1.addListener注册监听的方法,当对象改变的时候回调
/// Register a closure to be called when the object changes.
///
/// If the given closure is already registered, an additional instance is
/// added, and must be removed the same number of times it is added before it
/// will stop being called.
///
/// This method must not be called after [dispose] has been called.
///
/// @template flutter.foundation.ChangeNotifier.addListener
/// If a listener is added twice, and is removed once during an iteration
/// (e.g. in response to a notification), it will still be called again. If,
/// on the other hand, it is removed as many times as it was registered, then
/// it will no longer be called. This odd behavior is the result of the
/// [ChangeNotifier] not being able to determine which listener is being
/// removed, since they are identical, therefore it will conservatively still
/// call all the listeners when it knows that any are still registered.
///
/// This surprising behavior can be unexpectedly observed when registering a
/// listener on two separate objects which are both forwarding all
/// registrations to a common upstream object.
/// @endtemplate
///
/// See also:
///
/// * [removeListener], which removes a previously registered closure from
/// the list of closures that are notified when the object changes.
@override
void addListener(VoidCallback listener)
assert(_debugAssertNotDisposed());
if (_count == _listeners.length)
if (_count == 0)
_listeners = List<VoidCallback?>.filled(1, null);
else
final List<VoidCallback?> newListeners =
List<VoidCallback?>.filled(_listeners.length * 2, null);
for (int i = 0; i < _count; i++)
newListeners[i] = _listeners[i];
_listeners = newListeners;
_listeners[_count++] = listener;
2.removeListener,删除注册的监听,与addListener对应
/// Remove a previously registered closure from the list of closures that are
/// notified when the object changes.
///
/// If the given listener is not registered, the call is ignored.
///
/// This method must not be called after [dispose] has been called.
///
/// @macro flutter.foundation.ChangeNotifier.addListener
///
/// See also:
///
/// * [addListener], which registers a closure to be called when the object
/// changes.
@override
void removeListener(VoidCallback listener)
assert(_debugAssertNotDisposed());
for (int i = 0; i < _count; i++)
final VoidCallback? _listener = _listeners[i];
if (_listener == listener)
if (_notificationCallStackDepth > 0)
// We don't resize the list during notifyListeners iterations
// but we set to null, the listeners we want to remove. We will
// effectively resize the list at the end of all notifyListeners
// iterations.
_listeners[i] = null;
_reentrantlyRemovedListeners++;
else
// When we are outside the notifyListeners iterations we can
// effectively shrink the list.
_removeAt(i);
break;
3.dispose 丢弃对象使用的任何资源
/// Discards any resources used by the object. After this is called, the
/// object is not in a usable state and should be discarded (calls to
/// [addListener] and [removeListener] will throw after the object is
/// disposed).
///
/// This method should only be called by the object's owner.
@mustCallSuper
void dispose()
assert(_debugAssertNotDisposed());
assert(()
_debugDisposed = true;
return true;
());
三.ChangeNotifierTest 实例
// ignore: file_names
import 'package:flutter/material.dart';
class Counter extends ChangeNotifier
int _count =0;
int get count =>_count;
addCount()
_count++;
notifyListeners();
Counter _counter=new Counter();
class ChangeNotifierTest extends StatefulWidget
@override
_ChangeNotifierTestState createState() =>_ChangeNotifierTestState();
class _ChangeNotifierTestState extends State<ChangeNotifierTest>
@override
void initState()
// TODO: implement initState
super.initState();
_counter.addListener(() //add listener
print('new count is :$_counter.count');
);
@override
void dispose()
// TODO: implement dispose
super.dispose();
_counter.dispose();//remove listener
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'ChangeNotifier test',
home: Scaffold(
appBar: AppBar(
title: Text('ChangeNotifier test bar'),
),
body: Center(
child: Container(
child: RaisedButton(
onPressed: ()
_counter.addCount();
,
child: Text('count')
),
),
),
),
);
以上是关于Flutter 数据监听器ChangeNotifier的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中监听 Stream 并只向 DB 写入一次
在 Flutter 中监听 Firestore 集合及其子集合