From 9047830c2e03951eaebc2c192ee520fddca97d73 Mon Sep 17 00:00:00 2001 From: Hixie Date: Fri, 28 Aug 2015 10:52:23 -0700 Subject: [PATCH] Rationalise the Key API. Add a way of having keys based on numeric types or DateTimes by having a ValueKey class. Remove the redundant ways of declaring things, except for leaving one shorthand -- you can say `new Key(s)` instead of `new ValueKey(s)`. --- examples/fitness/lib/fitness_item.dart | 2 +- examples/mine_digger/lib/main.dart | 2 +- examples/widgets/card_collection.dart | 2 +- examples/widgets/ensure_visible.dart | 2 +- examples/widgets/overlay_geometry.dart | 2 +- examples/widgets/pageable_list.dart | 2 +- examples/widgets/tabs.dart | 10 +++++----- packages/flutter/lib/editing/input.dart | 2 +- packages/flutter/lib/widgets/basic.dart | 2 +- packages/flutter/lib/widgets/dialog.dart | 2 +- packages/flutter/lib/widgets/framework.dart | 15 ++++++--------- packages/flutter/lib/widgets/navigator.dart | 2 +- packages/unit/test/widget/mimic_test.dart | 6 +++--- packages/unit/test/widget/pageable_list_test.dart | 2 +- 14 files changed, 25 insertions(+), 28 deletions(-) diff --git a/examples/fitness/lib/fitness_item.dart b/examples/fitness/lib/fitness_item.dart index 4e7d906059..c868c07e38 100644 --- a/examples/fitness/lib/fitness_item.dart +++ b/examples/fitness/lib/fitness_item.dart @@ -30,7 +30,7 @@ abstract class FitnessItemRow extends Component { FitnessItemRow({ FitnessItem item, this.onDismissed }) : this.item = item, - super(key: new Key(item.when.toString())) { + super(key: new ValueKey(item.when)) { assert(onDismissed != null); } diff --git a/examples/mine_digger/lib/main.dart b/examples/mine_digger/lib/main.dart index 3b8e561f66..1384732aac 100644 --- a/examples/mine_digger/lib/main.dart +++ b/examples/mine_digger/lib/main.dart @@ -142,7 +142,7 @@ class MineDiggerApp extends App { new Row( row, justifyContent: FlexJustifyContent.center, - key: new Key.stringify(iy) + key: new ValueKey(iy) ) ); } diff --git a/examples/widgets/card_collection.dart b/examples/widgets/card_collection.dart index ceb0824c99..980bb12153 100644 --- a/examples/widgets/card_collection.dart +++ b/examples/widgets/card_collection.dart @@ -13,7 +13,7 @@ class CardModel { double height; Color color; String get label => "Item $value"; - Key get key => new Key.fromObjectIdentity(this); + Key get key => new ObjectKey(this); } class CardCollectionApp extends App { diff --git a/examples/widgets/ensure_visible.dart b/examples/widgets/ensure_visible.dart index d1cc9a0a94..1a07f084ce 100644 --- a/examples/widgets/ensure_visible.dart +++ b/examples/widgets/ensure_visible.dart @@ -12,7 +12,7 @@ class CardModel { double height; Color color; String get label => "Card $value"; - Key get key => new Key.fromObjectIdentity(this); + Key get key => new ObjectKey(this); } class EnsureVisibleApp extends App { diff --git a/examples/widgets/overlay_geometry.dart b/examples/widgets/overlay_geometry.dart index e31311ece3..b09abfb080 100644 --- a/examples/widgets/overlay_geometry.dart +++ b/examples/widgets/overlay_geometry.dart @@ -15,7 +15,7 @@ class CardModel { double height; Color color; String get label => "Card $value"; - Key get key => new Key.fromObjectIdentity(this); + Key get key => new ObjectKey(this); } enum MarkerType { topLeft, bottomRight, touch } diff --git a/examples/widgets/pageable_list.dart b/examples/widgets/pageable_list.dart index 3b4336e7ba..eac188c5c1 100644 --- a/examples/widgets/pageable_list.dart +++ b/examples/widgets/pageable_list.dart @@ -12,7 +12,7 @@ class CardModel { Size size; Color color; String get label => "Card $value"; - Key get key => new Key.fromObjectIdentity(this); + Key get key => new ObjectKey(this); } class PageableListApp extends App { diff --git a/examples/widgets/tabs.dart b/examples/widgets/tabs.dart index f434fc4ada..908cf7ef26 100644 --- a/examples/widgets/tabs.dart +++ b/examples/widgets/tabs.dart @@ -35,7 +35,7 @@ class TabbedNavigatorApp extends App { builder: () => _buildContent(text) ); }); - return _buildTabNavigator(n, views.toList(), const StringKey('textLabelsTabNavigator')); + return _buildTabNavigator(n, views.toList(), const ValueKey('textLabelsTabNavigator')); } TabNavigator _buildIconLabelsTabNavigator(int n) { @@ -46,7 +46,7 @@ class TabbedNavigatorApp extends App { builder: () => _buildContent(icon_name) ); }); - return _buildTabNavigator(n, views.toList(), const StringKey('iconLabelsTabNavigator')); + return _buildTabNavigator(n, views.toList(), const ValueKey('iconLabelsTabNavigator')); } TabNavigator _buildTextAndIconLabelsTabNavigator(int n) { @@ -64,7 +64,7 @@ class TabbedNavigatorApp extends App { builder: () => _buildContent("Summary") ) ]; - return _buildTabNavigator(n, views, const StringKey('textAndIconLabelsTabNavigator')); + return _buildTabNavigator(n, views, const ValueKey('textAndIconLabelsTabNavigator')); } TabNavigator _buildScrollableTabNavigator(int n) { @@ -86,7 +86,7 @@ class TabbedNavigatorApp extends App { builder: () => _buildContent(text) ); }); - return _buildTabNavigator(n, views.toList(), const StringKey('scrollableTabNavigator'), isScrollable: true); + return _buildTabNavigator(n, views.toList(), const ValueKey('scrollableTabNavigator'), isScrollable: true); } @@ -118,7 +118,7 @@ class TabbedNavigatorApp extends App { ) ]; - TabNavigator tabNavigator = _buildTabNavigator(4, views, const StringKey('tabs')); + TabNavigator tabNavigator = _buildTabNavigator(4, views, const ValueKey('tabs')); assert(selectedIndices.length == 5); ToolBar toolbar = new ToolBar( diff --git a/packages/flutter/lib/editing/input.dart b/packages/flutter/lib/editing/input.dart index 9a9ac76fa1..632e467fbd 100644 --- a/packages/flutter/lib/editing/input.dart +++ b/packages/flutter/lib/editing/input.dart @@ -75,7 +75,7 @@ class Input extends StatefulComponent { if (placeholder != null && _value.isEmpty) { Widget child = new Opacity( - key: const StringKey('placeholder'), + key: const ValueKey('placeholder'), child: new Text(placeholder, style: textStyle), opacity: themeData.hintOpacity ); diff --git a/packages/flutter/lib/widgets/basic.dart b/packages/flutter/lib/widgets/basic.dart index c9712525e4..b3a5e2b5cc 100644 --- a/packages/flutter/lib/widgets/basic.dart +++ b/packages/flutter/lib/widgets/basic.dart @@ -768,7 +768,7 @@ class AssetImage extends Component { class WidgetToRenderBoxAdapter extends LeafRenderObjectWrapper { WidgetToRenderBoxAdapter(RenderBox renderBox) : renderBox = renderBox, - super(key: new Key.fromObjectIdentity(renderBox)); + super(key: new ObjectKey(renderBox)); final RenderBox renderBox; diff --git a/packages/flutter/lib/widgets/dialog.dart b/packages/flutter/lib/widgets/dialog.dart index 23eeedccc8..979b7772a5 100644 --- a/packages/flutter/lib/widgets/dialog.dart +++ b/packages/flutter/lib/widgets/dialog.dart @@ -178,7 +178,7 @@ Future showDialog(Navigator navigator, DialogBuilder builder) { completer: completer, builder: (navigator, route) { return new Focus( - key: new GlobalKey.fromObjectIdentity(route), + key: new GlobalObjectKey(route), autofocus: true, child: builder(navigator) ); diff --git a/packages/flutter/lib/widgets/framework.dart b/packages/flutter/lib/widgets/framework.dart index 9617933d27..14421ef876 100644 --- a/packages/flutter/lib/widgets/framework.dart +++ b/packages/flutter/lib/widgets/framework.dart @@ -25,16 +25,14 @@ typedef void WidgetTreeWalker(Widget); abstract class Key { const Key.constructor(); // so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor - factory Key(String value) => new StringKey(value); - factory Key.stringify(Object value) => new StringKey(value.toString()); - factory Key.fromObjectIdentity(Object value) => new ObjectKey(value); + factory Key(String value) => new ValueKey(value); } -class StringKey extends Key { - const StringKey(this.value) : super.constructor(); - final String value; +class ValueKey extends Key { + const ValueKey(this.value) : super.constructor(); + final T value; String toString() => '[\'${value}\']'; - bool operator==(other) => other is StringKey && other.value == value; + bool operator==(other) => other is ValueKey && other.value == value; int get hashCode => value.hashCode; } @@ -51,8 +49,7 @@ typedef void GlobalKeyRemoveListener(GlobalKey key); abstract class GlobalKey extends Key { const GlobalKey.constructor() : super.constructor(); // so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor - factory GlobalKey({ String label }) => new LabeledGlobalKey(label); - factory GlobalKey.fromObjectIdentity(Object value) => new GlobalObjectKey(value); + factory GlobalKey({ String label }) => new LabeledGlobalKey(label); // the label is purely for debugging purposes and is otherwise ignored static final Map _registry = new Map(); static final Map _debugDuplicates = new Map(); diff --git a/packages/flutter/lib/widgets/navigator.dart b/packages/flutter/lib/widgets/navigator.dart index f23a751e29..b848a97592 100644 --- a/packages/flutter/lib/widgets/navigator.dart +++ b/packages/flutter/lib/widgets/navigator.dart @@ -186,7 +186,7 @@ class Navigator extends StatefulComponent { } if (child == null) continue; - TransitionBase transition = historyEntry.route.buildTransition(key: new Key.fromObjectIdentity(historyEntry)) + TransitionBase transition = historyEntry.route.buildTransition(key: new ObjectKey(historyEntry)) ..child = child ..direction = (i <= state.historyIndex) ? Direction.forward : Direction.reverse ..onDismissed = () { diff --git a/packages/unit/test/widget/mimic_test.dart b/packages/unit/test/widget/mimic_test.dart index 55347d1215..ca51a5ee89 100644 --- a/packages/unit/test/widget/mimic_test.dart +++ b/packages/unit/test/widget/mimic_test.dart @@ -13,7 +13,7 @@ void main() { new Mimicable( key: globalKey, child: new Container( - key: new Key.stringify('inner'), + key: new Key('inner'), height: 10.0, width: 10.0 ) @@ -50,13 +50,13 @@ void main() { tester.pumpFrame(() { return new Flex([ new Container( - key: new Key.stringify('outer'), + key: new Key('outer'), height: 10.0, width: 10.0, child: new Mimicable( key: globalKey, child: new Container( - key: new Key.stringify('inner'), + key: new Key('inner'), height: 10.0, width: 10.0 ) diff --git a/packages/unit/test/widget/pageable_list_test.dart b/packages/unit/test/widget/pageable_list_test.dart index f560eefa8e..833cfe46cd 100644 --- a/packages/unit/test/widget/pageable_list_test.dart +++ b/packages/unit/test/widget/pageable_list_test.dart @@ -14,7 +14,7 @@ void main() { Widget buildPage(int page) { return new Container( - key: new StringKey(page.toString()), + key: new ValueKey(page), width: pageSize.width, height: pageSize.height, child: new Text(page.toString())