tabs_demo.dart 6.8 KB
Newer Older
1 2 3 4 5 6
// 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.

import 'package:flutter/material.dart';

7 8 9
// Each TabBarView contains a _Page and for each _Page there is a list
// of _CardData objects. Each _CardData object is displayed by a _CardItem.

10 11
const String _kGalleryAssetsPackage = 'flutter_gallery_assets';

12 13 14
class _Page {
  _Page({ this.label });
  final String label;
15
  String get id => label[0];
16 17
  @override
  String toString() => '$runtimeType("$label")';
18 19 20
}

class _CardData {
21
  const _CardData({ this.title, this.imageAsset, this.imageAssetPackage });
22 23
  final String title;
  final String imageAsset;
24
  final String imageAssetPackage;
25 26
}

27 28 29 30
final Map<_Page, List<_CardData>> _allPages = <_Page, List<_CardData>>{
  new _Page(label: 'LEFT'): <_CardData>[
    const _CardData(
      title: 'Vintage Bluetooth Radio',
31 32
      imageAsset: 'shrine/products/radio.png',
      imageAssetPackage: _kGalleryAssetsPackage,
33 34 35
    ),
    const _CardData(
      title: 'Sunglasses',
36 37
      imageAsset: 'shrine/products/sunnies.png',
      imageAssetPackage: _kGalleryAssetsPackage,
38 39 40
    ),
    const _CardData(
      title: 'Clock',
41 42
      imageAsset: 'shrine/products/clock.png',
      imageAssetPackage: _kGalleryAssetsPackage,
43 44 45
    ),
    const _CardData(
      title: 'Red popsicle',
46 47
      imageAsset: 'shrine/products/popsicle.png',
      imageAssetPackage: _kGalleryAssetsPackage,
48 49 50
    ),
    const _CardData(
      title: 'Folding Chair',
51 52
      imageAsset: 'shrine/products/lawn_chair.png',
      imageAssetPackage: _kGalleryAssetsPackage,
53 54 55
    ),
    const _CardData(
      title: 'Green comfort chair',
56 57
      imageAsset: 'shrine/products/chair.png',
      imageAssetPackage: _kGalleryAssetsPackage,
58 59 60
    ),
    const _CardData(
      title: 'Old Binoculars',
61 62
      imageAsset: 'shrine/products/binoculars.png',
      imageAssetPackage: _kGalleryAssetsPackage,
63 64 65
    ),
    const _CardData(
      title: 'Teapot',
66 67
      imageAsset: 'shrine/products/teapot.png',
      imageAssetPackage: _kGalleryAssetsPackage,
68 69 70
    ),
    const _CardData(
      title: 'Blue suede shoes',
71 72
      imageAsset: 'shrine/products/chucks.png',
      imageAssetPackage: _kGalleryAssetsPackage,
73
    ),
74 75 76 77 78 79 80
  ],
  new _Page(label: 'RIGHT'): <_CardData>[
    const _CardData(
      title: 'Beachball',
      imageAsset: 'shrine/products/beachball.png',
      imageAssetPackage: _kGalleryAssetsPackage,
    ),
81 82
    const _CardData(
      title: 'Dipped Brush',
83 84
      imageAsset: 'shrine/products/brush.png',
      imageAssetPackage: _kGalleryAssetsPackage,
85 86 87
    ),
    const _CardData(
      title: 'Perfect Goldfish Bowl',
88 89
      imageAsset: 'shrine/products/fish_bowl.png',
      imageAssetPackage: _kGalleryAssetsPackage,
90
    ),
91
  ],
92 93 94
};

class _CardDataItem extends StatelessWidget {
95
  const _CardDataItem({ this.page, this.data });
96

97
  static const double height = 272.0;
98 99 100 101 102 103 104 105 106 107 108 109 110 111
  final _Page page;
  final _CardData data;

  @override
  Widget build(BuildContext context) {
    return new Card(
      child: new Padding(
        padding: const EdgeInsets.all(16.0),
        child: new Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            new Align(
              alignment: page.id == 'L'
112 113
                ? Alignment.centerLeft
                : Alignment.centerRight,
114
              child: new CircleAvatar(child: new Text('${page.id}')),
115 116 117 118
            ),
            new SizedBox(
              width: 144.0,
              height: 144.0,
119 120 121 122 123
              child: new Image.asset(
                data.imageAsset,
                package: data.imageAssetPackage,
                fit: BoxFit.contain,
              ),
124 125
            ),
            new Center(
126 127 128 129
              child: new Text(
                data.title,
                style: Theme.of(context).textTheme.title,
              ),
130 131 132 133
            ),
          ],
        ),
      ),
134 135 136
    );
  }
}
137

Hans Muller's avatar
Hans Muller committed
138
class TabsDemo extends StatelessWidget {
139
  static const String routeName = '/material/tabs';
140

141
  @override
142
  Widget build(BuildContext context) {
Hans Muller's avatar
Hans Muller committed
143 144
    return new DefaultTabController(
      length: _allPages.length,
145
      child: new Scaffold(
146 147 148
        body: new NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return <Widget>[
149 150 151 152 153 154 155 156 157 158 159 160
              new SliverOverlapAbsorber(
                handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                child: new SliverAppBar(
                  title: const Text('Tabs and scrolling'),
                  pinned: true,
                  expandedHeight: 150.0,
                  forceElevated: innerBoxIsScrolled,
                  bottom: new TabBar(
                    tabs: _allPages.keys.map(
                      (_Page page) => new Tab(text: page.label),
                    ).toList(),
                  ),
161 162 163 164 165 166
                ),
              ),
            ];
          },
          body: new TabBarView(
            children: _allPages.keys.map((_Page page) {
167 168 169
              return new SafeArea(
                top: false,
                bottom: false,
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
                child: new Builder(
                  builder: (BuildContext context) {
                    return new CustomScrollView(
                      key: new PageStorageKey<_Page>(page),
                      slivers: <Widget>[
                        new SliverOverlapInjector(
                          handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                        ),
                        new SliverPadding(
                          padding: const EdgeInsets.symmetric(
                            vertical: 8.0,
                            horizontal: 16.0,
                          ),
                          sliver: new SliverFixedExtentList(
                            itemExtent: _CardDataItem.height,
                            delegate: new SliverChildBuilderDelegate(
                              (BuildContext context, int index) {
                                final _CardData data = _allPages[page][index];
                                return new Padding(
                                  padding: const EdgeInsets.symmetric(
                                    vertical: 8.0,
                                  ),
                                  child: new _CardDataItem(
                                    page: page,
                                    data: data,
                                  ),
                                );
                              },
                              childCount: _allPages[page].length,
                            ),
                          ),
                        ),
                      ],
203
                    );
204
                  },
205
                ),
206 207
              );
            }).toList(),
Hans Muller's avatar
Hans Muller committed
208
          ),
209
        ),
Hans Muller's avatar
Hans Muller committed
210
      ),
211 212 213
    );
  }
}