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 集合及其子集合

Flutter 监听 Stateless Widget 上的生命周期事件?

Flutter Futures:等待侦听器至少完成一次

Flutter 中的应用级别或全局 Steam 监听

如何向 Flutter.EventChannel 添加多个监听器?