Rationalise the Key API.
Add a way of having keys based on numeric types or DateTimes by having a ValueKey<T> class. Remove the redundant ways of declaring things, except for leaving one shorthand -- you can say `new Key(s)` instead of `new ValueKey<String>(s)`.
This commit is contained in:
@@ -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<DateTime>(item.when)) {
|
||||
assert(onDismissed != null);
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ class MineDiggerApp extends App {
|
||||
new Row(
|
||||
row,
|
||||
justifyContent: FlexJustifyContent.center,
|
||||
key: new Key.stringify(iy)
|
||||
key: new ValueKey<int>(iy)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<String>('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<String>('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<String>('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<String>('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<String>('tabs'));
|
||||
assert(selectedIndices.length == 5);
|
||||
|
||||
ToolBar toolbar = new ToolBar(
|
||||
|
||||
@@ -75,7 +75,7 @@ class Input extends StatefulComponent {
|
||||
|
||||
if (placeholder != null && _value.isEmpty) {
|
||||
Widget child = new Opacity(
|
||||
key: const StringKey('placeholder'),
|
||||
key: const ValueKey<String>('placeholder'),
|
||||
child: new Text(placeholder, style: textStyle),
|
||||
opacity: themeData.hintOpacity
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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<String>(value);
|
||||
}
|
||||
|
||||
class StringKey extends Key {
|
||||
const StringKey(this.value) : super.constructor();
|
||||
final String value;
|
||||
class ValueKey<T> 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<T> && 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<GlobalKey, Widget> _registry = new Map<GlobalKey, Widget>();
|
||||
static final Map<GlobalKey, int> _debugDuplicates = new Map<GlobalKey, int>();
|
||||
|
||||
@@ -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 = () {
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ void main() {
|
||||
|
||||
Widget buildPage(int page) {
|
||||
return new Container(
|
||||
key: new StringKey(page.toString()),
|
||||
key: new ValueKey<int>(page),
|
||||
width: pageSize.width,
|
||||
height: pageSize.height,
|
||||
child: new Text(page.toString())
|
||||
|
||||
Reference in New Issue
Block a user