stock_symbol_viewer.dart 4.03 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
Hixie's avatar
Hixie committed
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6 7
import 'package:flutter/material.dart';

import 'stock_arrow.dart';
8
import 'stock_data.dart';
Hixie's avatar
Hixie committed
9

10
class _StockSymbolView extends StatelessWidget {
11
  const _StockSymbolView({ this.stock, this.arrow });
Hixie's avatar
Hixie committed
12 13

  final Stock stock;
14
  final Widget arrow;
Hixie's avatar
Hixie committed
15

16
  @override
Hixie's avatar
Hixie committed
17
  Widget build(BuildContext context) {
18
    assert(stock != null);
19 20
    final String lastSale = '\$${stock.lastSale.toStringAsFixed(2)}';
    String changeInPrice = '${stock.percentChange.toStringAsFixed(2)}%';
21
    if (stock.percentChange > 0)
22
      changeInPrice = '+' + changeInPrice;
23

24
    final TextStyle headings = Theme.of(context).textTheme.bodyText1;
25
    return Container(
26
      padding: const EdgeInsets.all(20.0),
27
      child: Column(
28
        children: <Widget>[
29
          Row(
30
            children: <Widget>[
31
              Text(
32
                stock.symbol,
33
                key: ValueKey<String>('${stock.symbol}_symbol_name'),
34
                style: Theme.of(context).textTheme.headline3,
35
              ),
36
              arrow,
37
            ],
38
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
39
          ),
40 41 42
          Text('Last Sale', style: headings),
          Text('$lastSale ($changeInPrice)'),
          Container(
43 44
            height: 8.0
          ),
45
          Text('Market Cap', style: headings),
46
          Text(stock.marketCap),
47
          Container(
48 49
            height: 8.0
          ),
50 51
          RichText(
            text: TextSpan(
52
              style: DefaultTextStyle.of(context).style.merge(const TextStyle(fontSize: 8.0)),
53
              text: 'Prices may be delayed by ',
54
              children: const <TextSpan>[
55 56
                TextSpan(text: 'several', style: TextStyle(fontStyle: FontStyle.italic)),
                TextSpan(text: ' years.'),
57 58
              ],
            ),
59
          ),
60
        ],
61 62
        mainAxisSize: MainAxisSize.min,
      ),
63 64 65 66
    );
  }
}

67
class StockSymbolPage extends StatelessWidget {
68
  const StockSymbolPage({ this.symbol, this.stocks });
69

70 71
  final String symbol;
  final StockData stocks;
72

73
  @override
74
  Widget build(BuildContext context) {
75
    return AnimatedBuilder(
76 77 78
      animation: stocks,
      builder: (BuildContext context, Widget child) {
        final Stock stock = stocks[symbol];
79 80
        return Scaffold(
          appBar: AppBar(
81
            title: Text(stock?.name ?? symbol),
82
          ),
83 84
          body: SingleChildScrollView(
            child: Container(
85
              margin: const EdgeInsets.all(20.0),
86 87
              child: Card(
                child: AnimatedCrossFade(
88 89
                  duration: const Duration(milliseconds: 300),
                  firstChild: const Padding(
90 91
                    padding: EdgeInsets.all(20.0),
                    child: Center(child: CircularProgressIndicator()),
92 93
                  ),
                  secondChild: stock != null
94
                    ? _StockSymbolView(
95
                      stock: stock,
96
                      arrow: Hero(
97
                        tag: stock,
98
                        child: StockArrow(percentChange: stock.percentChange),
99
                      ),
100
                    ) : Padding(
101
                        padding: const EdgeInsets.all(20.0),
102
                        child: Center(child: Text('$symbol not found')),
103 104 105
                    ),
                  crossFadeState: stock == null && stocks.loading ? CrossFadeState.showFirst : CrossFadeState.showSecond,
                ),
106 107 108
              ),
            ),
          ),
109 110
        );
      },
Hixie's avatar
Hixie committed
111 112
    );
  }
113 114
}

115
class StockSymbolBottomSheet extends StatelessWidget {
116
  const StockSymbolBottomSheet({ this.stock });
117 118

  final Stock stock;
Hixie's avatar
Hixie committed
119

120
  @override
121
  Widget build(BuildContext context) {
122
    return Container(
123
      padding: const EdgeInsets.all(10.0),
124
      decoration: const BoxDecoration(
125
        border: Border(top: BorderSide(color: Colors.black26))
126
      ),
127
      child: _StockSymbolView(
128
        stock: stock,
129 130
        arrow: StockArrow(percentChange: stock.percentChange),
      ),
131 132
   );
  }
Hixie's avatar
Hixie committed
133
}