tabs_demo.dart 6.7 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
import '../../gallery/demo.dart';

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

12 13
const String _kGalleryAssetsPackage = 'flutter_gallery_assets';

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

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

29
final Map<_Page, List<_CardData>> _allPages = <_Page, List<_CardData>>{
30
  _Page(label: 'HOME'): <_CardData>[
31
    const _CardData(
32
      title: 'Flatwear',
33
      imageAsset: 'products/flatwear.png',
34
      imageAssetPackage: _kGalleryAssetsPackage,
35 36
    ),
    const _CardData(
37
      title: 'Pine Table',
38
      imageAsset: 'products/table.png',
39
      imageAssetPackage: _kGalleryAssetsPackage,
40 41
    ),
    const _CardData(
42
      title: 'Blue Cup',
43
      imageAsset: 'products/cup.png',
44
      imageAssetPackage: _kGalleryAssetsPackage,
45 46
    ),
    const _CardData(
47
      title: 'Tea Set',
48
      imageAsset: 'products/teaset.png',
49
      imageAssetPackage: _kGalleryAssetsPackage,
50 51
    ),
    const _CardData(
52
      title: 'Desk Set',
53
      imageAsset: 'products/deskset.png',
54
      imageAssetPackage: _kGalleryAssetsPackage,
55 56
    ),
    const _CardData(
57
      title: 'Blue Linen Napkins',
58
      imageAsset: 'products/napkins.png',
59
      imageAssetPackage: _kGalleryAssetsPackage,
60 61
    ),
    const _CardData(
62
      title: 'Planters',
63
      imageAsset: 'products/planters.png',
64
      imageAssetPackage: _kGalleryAssetsPackage,
65 66
    ),
    const _CardData(
67
      title: 'Kitchen Quattro',
68
      imageAsset: 'products/kitchen_quattro.png',
69
      imageAssetPackage: _kGalleryAssetsPackage,
70 71
    ),
    const _CardData(
72
      title: 'Platter',
73
      imageAsset: 'products/platter.png',
74
      imageAssetPackage: _kGalleryAssetsPackage,
75
    ),
76
  ],
77
  _Page(label: 'APPAREL'): <_CardData>[
78
    const _CardData(
79
      title: 'Cloud-White Dress',
80
      imageAsset: 'products/dress.png',
81 82
      imageAssetPackage: _kGalleryAssetsPackage,
    ),
83
    const _CardData(
84
      title: 'Ginger Scarf',
85
      imageAsset: 'products/scarf.png',
86
      imageAssetPackage: _kGalleryAssetsPackage,
87 88
    ),
    const _CardData(
89
      title: 'Blush Sweats',
90
      imageAsset: 'products/sweats.png',
91
      imageAssetPackage: _kGalleryAssetsPackage,
92
    ),
93
  ],
94 95 96
};

class _CardDataItem extends StatelessWidget {
97
  const _CardDataItem({ this.page, this.data });
98

99
  static const double height = 272.0;
100 101 102 103 104
  final _Page page;
  final _CardData data;

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

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

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