flutter/examples/stocks/lib/stock_row.dart
Ian Hickson d5e072c35b Fix crash when going back in stocks app.
Heroes with the same tag have to have keys that are unique across the
entire subtree. Since we can now show both stock lists, this means we
have to include the tab in the heroes' keys.

Fixes #668.
2015-12-01 22:54:11 -08:00

110 lines
3.5 KiB
Dart

// Copyright 2015 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.
part of stocks;
enum StockRowPartKind { arrow }
class StockRowPartKey extends Key {
const StockRowPartKey(this.keySalt, this.stock, this.part) : super.constructor();
final Object keySalt;
final Stock stock;
final StockRowPartKind part;
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
final StockRowPartKey typedOther = other;
return keySalt == typedOther.keySalt
&& stock == typedOther.stock
&& part == typedOther.part;
}
int get hashCode => 37 * (37 * (37 * (373) + identityHashCode(keySalt)) + identityHashCode(stock)) + identityHashCode(part);
String toString() => '[$runtimeType ${keySalt.toString().split(".")[1]}:${stock.symbol}:${part.toString().split(".")[1]}]';
}
typedef void StockRowActionCallback(Stock stock, Key arrowKey);
class StockRow extends StatelessComponent {
StockRow({
Stock stock,
Object keySalt,
this.onPressed,
this.onDoubleTap,
this.onLongPressed
}) : this.stock = stock,
_arrowKey = new StockRowPartKey(keySalt, stock, StockRowPartKind.arrow),
super(key: new ObjectKey(stock));
final Stock stock;
final StockRowActionCallback onPressed;
final StockRowActionCallback onDoubleTap;
final StockRowActionCallback onLongPressed;
final Key _arrowKey;
static const double kHeight = 79.0;
GestureTapCallback _getHandler(StockRowActionCallback callback) {
return callback == null ? null : () => callback(stock, _arrowKey);
}
Widget build(BuildContext context) {
final String lastSale = "\$${stock.lastSale.toStringAsFixed(2)}";
String changeInPrice = "${stock.percentChange.toStringAsFixed(2)}%";
if (stock.percentChange > 0)
changeInPrice = "+" + changeInPrice;
return new InkWell(
onTap: _getHandler(onPressed),
onDoubleTap: _getHandler(onDoubleTap),
onLongPress: _getHandler(onLongPressed),
child: new Container(
padding: const EdgeDims.TRBL(16.0, 16.0, 20.0, 16.0),
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(color: Theme.of(context).dividerColor)
)
),
child: new Row(<Widget>[
new Container(
margin: const EdgeDims.only(right: 5.0),
child: new Hero(
tag: StockRowPartKind.arrow,
key: _arrowKey,
child: new StockArrow(percentChange: stock.percentChange)
)
),
new Flexible(
child: new Row(<Widget>[
new Flexible(
flex: 2,
child: new Text(
stock.symbol
)
),
new Flexible(
child: new Text(
lastSale,
style: const TextStyle(textAlign: TextAlign.right)
)
),
new Flexible(
child: new Text(
changeInPrice,
style: const TextStyle(textAlign: TextAlign.right)
)
),
],
alignItems: FlexAlignItems.baseline,
textBaseline: DefaultTextStyle.of(context).textBaseline
)
),
]
)
)
);
}
}