Commit 05862000 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Extract a Listenable base class from Animation and ChangeNotifier (#5889)

Having this base class lets classes like CustomPainter and DataTableSource be
more agnostic as to what's generating the repaints.
parent 179ea4a0
...@@ -14,6 +14,7 @@ export 'src/foundation/basic_types.dart'; ...@@ -14,6 +14,7 @@ export 'src/foundation/basic_types.dart';
export 'src/foundation/binding.dart'; export 'src/foundation/binding.dart';
export 'src/foundation/change_notifier.dart'; export 'src/foundation/change_notifier.dart';
export 'src/foundation/licenses.dart'; export 'src/foundation/licenses.dart';
export 'src/foundation/listenable.dart';
export 'src/foundation/platform.dart'; export 'src/foundation/platform.dart';
export 'src/foundation/print.dart'; export 'src/foundation/print.dart';
export 'src/foundation/synchronous_future.dart'; export 'src/foundation/synchronous_future.dart';
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
import 'dart:ui' show VoidCallback; import 'dart:ui' show VoidCallback;
import 'package:flutter/foundation.dart';
/// The status of an animation /// The status of an animation
enum AnimationStatus { enum AnimationStatus {
/// The animation is stopped at the beginning /// The animation is stopped at the beginning
...@@ -36,7 +38,7 @@ typedef void AnimationStatusListener(AnimationStatus status); ...@@ -36,7 +38,7 @@ typedef void AnimationStatusListener(AnimationStatus status);
/// ///
/// To create a new animation that you can run forward and backward, consider /// To create a new animation that you can run forward and backward, consider
/// using [AnimationController]. /// using [AnimationController].
abstract class Animation<T> { abstract class Animation<T> extends Listenable {
/// Abstract const constructor. This constructor enables subclasses to provide /// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions. /// const constructors so that they can be used in const expressions.
const Animation(); const Animation();
...@@ -46,11 +48,13 @@ abstract class Animation<T> { ...@@ -46,11 +48,13 @@ abstract class Animation<T> {
/// Calls the listener every time the value of the animation changes. /// Calls the listener every time the value of the animation changes.
/// ///
/// Listeners can be removed with [removeListener]. /// Listeners can be removed with [removeListener].
@override
void addListener(VoidCallback listener); void addListener(VoidCallback listener);
/// Stop calling the listener every time the value of the animation changes. /// Stop calling the listener every time the value of the animation changes.
/// ///
/// Listeners can be added with [addListener]. /// Listeners can be added with [addListener].
@override
void removeListener(VoidCallback listener); void removeListener(VoidCallback listener);
/// Calls listener every time the status of the animation changes. /// Calls listener every time the status of the animation changes.
......
...@@ -6,13 +6,15 @@ import 'package:meta/meta.dart'; ...@@ -6,13 +6,15 @@ import 'package:meta/meta.dart';
import 'assertions.dart'; import 'assertions.dart';
import 'basic_types.dart'; import 'basic_types.dart';
import 'listenable.dart';
/// Abstract class that can be extended or mixed in that provides /// A class that can be extended or mixed in that provides a change notification
/// a change notification API using [VoidCallback] for notifications. /// API using [VoidCallback] for notifications.
abstract class ChangeNotifier { class ChangeNotifier extends Listenable {
List<VoidCallback> _listeners; List<VoidCallback> _listeners;
/// Register a closure to be called when the object changes. /// Register a closure to be called when the object changes.
@override
void addListener(VoidCallback listener) { void addListener(VoidCallback listener) {
_listeners ??= <VoidCallback>[]; _listeners ??= <VoidCallback>[];
_listeners.add(listener); _listeners.add(listener);
...@@ -20,6 +22,7 @@ abstract class ChangeNotifier { ...@@ -20,6 +22,7 @@ abstract class ChangeNotifier {
/// Remove a previously registered closure from the list of closures that are /// Remove a previously registered closure from the list of closures that are
/// notified when the object changes. /// notified when the object changes.
@override
void removeListener(VoidCallback listener) { void removeListener(VoidCallback listener) {
_listeners?.remove(listener); _listeners?.remove(listener);
} }
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'basic_types.dart';
/// An object that maintains a list of listeners.
abstract class Listenable {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Listenable();
/// Register a closure to be called when the object notifies its listeners.
void addListener(VoidCallback listener);
/// Remove a previously registered closure from the list of closures that the
/// object notifies.
void removeListener(VoidCallback listener);
}
...@@ -59,4 +59,4 @@ abstract class DataTableSource extends ChangeNotifier { ...@@ -59,4 +59,4 @@ abstract class DataTableSource extends ChangeNotifier {
/// ///
/// If the selected row count changes, call [notifyListeners]. /// If the selected row count changes, call [notifyListeners].
int get selectedRowCount; int get selectedRowCount;
} }
\ No newline at end of file
...@@ -426,6 +426,12 @@ class _DialState extends State<_Dial> { ...@@ -426,6 +426,12 @@ class _DialState extends State<_Dial> {
_animateTo(_getThetaForTime(config.selectedTime)); _animateTo(_getThetaForTime(config.selectedTime));
} }
@override
void dispose() {
_thetaController.dispose();
super.dispose();
}
Tween<double> _thetaTween; Tween<double> _thetaTween;
Animation<double> _theta; Animation<double> _theta;
AnimationController _thetaController; AnimationController _thetaController;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/animation.dart'; import 'package:flutter/foundation.dart';
import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart';
import 'box.dart'; import 'box.dart';
...@@ -54,10 +54,10 @@ abstract class FlowPaintingContext { ...@@ -54,10 +54,10 @@ abstract class FlowPaintingContext {
/// * [Flow] /// * [Flow]
/// * [RenderFlow] /// * [RenderFlow]
abstract class FlowDelegate { abstract class FlowDelegate {
/// The flow will repaint whenever the [repaint] animation ticks. /// The flow will repaint whenever [repaint] notifies its listeners.
const FlowDelegate({ Animation<dynamic> repaint }) : _repaint = repaint; const FlowDelegate({ Listenable repaint }) : _repaint = repaint;
final Animation<dynamic> _repaint; final Listenable _repaint;
/// Override to control the size of the container for the children. /// Override to control the size of the container for the children.
/// ///
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import 'dart:ui' as ui show ImageFilter; import 'dart:ui' as ui show ImageFilter;
import 'package:flutter/animation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart';
...@@ -1490,10 +1490,10 @@ class RenderFractionalTranslation extends RenderProxyBox { ...@@ -1490,10 +1490,10 @@ class RenderFractionalTranslation extends RenderProxyBox {
abstract class CustomPainter { abstract class CustomPainter {
/// Creates a custom painter. /// Creates a custom painter.
/// ///
/// The painter will repaint whenever the [repaint] animation ticks. /// The painter will repaint whenever [repaint] notifies its listeners.
const CustomPainter({ Animation<dynamic> repaint }) : _repaint = repaint; const CustomPainter({ Listenable repaint }) : _repaint = repaint;
final Animation<dynamic> _repaint; final Listenable _repaint;
/// Called whenever the object needs to paint. The given [Canvas] has its /// Called whenever the object needs to paint. The given [Canvas] has its
/// coordinate space configured such that the origin is at the top left of the /// coordinate space configured such that the origin is at the top left of the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment