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';
export 'src/foundation/binding.dart';
export 'src/foundation/change_notifier.dart';
export 'src/foundation/licenses.dart';
export 'src/foundation/listenable.dart';
export 'src/foundation/platform.dart';
export 'src/foundation/print.dart';
export 'src/foundation/synchronous_future.dart';
......@@ -4,6 +4,8 @@
import 'dart:ui' show VoidCallback;
import 'package:flutter/foundation.dart';
/// The status of an animation
enum AnimationStatus {
/// The animation is stopped at the beginning
......@@ -36,7 +38,7 @@ typedef void AnimationStatusListener(AnimationStatus status);
///
/// To create a new animation that you can run forward and backward, consider
/// using [AnimationController].
abstract class Animation<T> {
abstract class Animation<T> extends Listenable {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Animation();
......@@ -46,11 +48,13 @@ abstract class Animation<T> {
/// Calls the listener every time the value of the animation changes.
///
/// Listeners can be removed with [removeListener].
@override
void addListener(VoidCallback listener);
/// Stop calling the listener every time the value of the animation changes.
///
/// Listeners can be added with [addListener].
@override
void removeListener(VoidCallback listener);
/// Calls listener every time the status of the animation changes.
......
......@@ -6,13 +6,15 @@ import 'package:meta/meta.dart';
import 'assertions.dart';
import 'basic_types.dart';
import 'listenable.dart';
/// Abstract class that can be extended or mixed in that provides
/// a change notification API using [VoidCallback] for notifications.
abstract class ChangeNotifier {
/// A class that can be extended or mixed in that provides a change notification
/// API using [VoidCallback] for notifications.
class ChangeNotifier extends Listenable {
List<VoidCallback> _listeners;
/// Register a closure to be called when the object changes.
@override
void addListener(VoidCallback listener) {
_listeners ??= <VoidCallback>[];
_listeners.add(listener);
......@@ -20,6 +22,7 @@ abstract class ChangeNotifier {
/// Remove a previously registered closure from the list of closures that are
/// notified when the object changes.
@override
void removeListener(VoidCallback 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 {
///
/// If the selected row count changes, call [notifyListeners].
int get selectedRowCount;
}
\ No newline at end of file
}
......@@ -426,6 +426,12 @@ class _DialState extends State<_Dial> {
_animateTo(_getThetaForTime(config.selectedTime));
}
@override
void dispose() {
_thetaController.dispose();
super.dispose();
}
Tween<double> _thetaTween;
Animation<double> _theta;
AnimationController _thetaController;
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
import 'package:vector_math/vector_math_64.dart';
import 'box.dart';
......@@ -54,10 +54,10 @@ abstract class FlowPaintingContext {
/// * [Flow]
/// * [RenderFlow]
abstract class FlowDelegate {
/// The flow will repaint whenever the [repaint] animation ticks.
const FlowDelegate({ Animation<dynamic> repaint }) : _repaint = repaint;
/// The flow will repaint whenever [repaint] notifies its listeners.
const FlowDelegate({ Listenable repaint }) : _repaint = repaint;
final Animation<dynamic> _repaint;
final Listenable _repaint;
/// Override to control the size of the container for the children.
///
......
......@@ -4,7 +4,7 @@
import 'dart:ui' as ui show ImageFilter;
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:meta/meta.dart';
import 'package:vector_math/vector_math_64.dart';
......@@ -1490,10 +1490,10 @@ class RenderFractionalTranslation extends RenderProxyBox {
abstract class CustomPainter {
/// Creates a custom painter.
///
/// The painter will repaint whenever the [repaint] animation ticks.
const CustomPainter({ Animation<dynamic> repaint }) : _repaint = repaint;
/// The painter will repaint whenever [repaint] notifies its listeners.
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
/// 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