From c319b890b33f2c15af043f2ab857e7c2944beefa Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Mon, 29 Oct 2018 19:44:36 -0700 Subject: [PATCH] Allow ChangeNotifier to be mixed in again (#23631) Luckily this class didn't actually need to extend its superclass, it only implements the interface. So we can change `extends` to `implements` and that's close enough, while allowing the class to be mixed in again. --- .../lib/src/foundation/change_notifier.dart | 2 +- .../test/foundation/change_notifier_test.dart | 35 ++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/packages/flutter/lib/src/foundation/change_notifier.dart b/packages/flutter/lib/src/foundation/change_notifier.dart index 566dada999..13a2e6d0ec 100644 --- a/packages/flutter/lib/src/foundation/change_notifier.dart +++ b/packages/flutter/lib/src/foundation/change_notifier.dart @@ -99,7 +99,7 @@ abstract class ValueListenable extends Listenable { /// See also: /// /// * [ValueNotifier], which is a [ChangeNotifier] that wraps a single value. -class ChangeNotifier extends Listenable { +class ChangeNotifier implements Listenable { ObserverList _listeners = ObserverList(); bool _debugAssertNotDisposed() { diff --git a/packages/flutter/test/foundation/change_notifier_test.dart b/packages/flutter/test/foundation/change_notifier_test.dart index 85c2194eca..7897c41dc1 100644 --- a/packages/flutter/test/foundation/change_notifier_test.dart +++ b/packages/flutter/test/foundation/change_notifier_test.dart @@ -11,6 +11,24 @@ class TestNotifier extends ChangeNotifier { } } +class HasListenersTester extends ValueNotifier { + HasListenersTester(T value) : super(value); + bool get testHasListeners => hasListeners; +} + +class A { + bool result = false; + void test() { result = true; } +} + +class B extends A with ChangeNotifier { + @override + void test() { + notifyListeners(); + super.test(); + } +} + void main() { testWidgets('ChangeNotifier', (WidgetTester tester) async { final List log = []; @@ -258,9 +276,18 @@ void main() { notifier.removeListener(test2); expect(notifier.testHasListeners, isFalse); }); -} -class HasListenersTester extends ValueNotifier { - HasListenersTester(T value) : super(value); - bool get testHasListeners => hasListeners; + test('ChangeNotifier as a mixin', () { + // We document that this is a valid way to use this class. + final B b = B(); + int notifications = 0; + b.addListener(() { + notifications += 1; + }); + expect(b.result, isFalse); + expect(notifications, 0); + b.test(); + expect(b.result, isTrue); + expect(notifications, 1); + }); }