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.
This commit is contained in:
Ian Hickson 2018-10-29 19:44:36 -07:00 committed by GitHub
parent 4a094de290
commit c319b890b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 5 deletions

View file

@ -99,7 +99,7 @@ abstract class ValueListenable<T> extends Listenable {
/// See also:
///
/// * [ValueNotifier], which is a [ChangeNotifier] that wraps a single value.
class ChangeNotifier extends Listenable {
class ChangeNotifier implements Listenable {
ObserverList<VoidCallback> _listeners = ObserverList<VoidCallback>();
bool _debugAssertNotDisposed() {

View file

@ -11,6 +11,24 @@ class TestNotifier extends ChangeNotifier {
}
}
class HasListenersTester<T> extends ValueNotifier<T> {
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<String> log = <String>[];
@ -258,9 +276,18 @@ void main() {
notifier.removeListener(test2);
expect(notifier.testHasListeners, isFalse);
});
}
class HasListenersTester<T> extends ValueNotifier<T> {
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);
});
}