Flutter 数据监听器ChangeNotifier

本文介绍了Flutter SDK中的ChangeNotifier类,它用于实现状态变化的通知机制。ChangeNotifier通过addListener和removeListener方法来注册和移除监听器,当对象状态改变时会触发回调。同时,文章提供了一个Counter类的示例,展示了如何创建一个基于ChangeNotifier的可观察对象,并在实践中应用。
摘要由CSDN通过智能技术生成

一.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')
            ),
          ),
        ),
      ),
    );
  }

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值