scrollable_tabs_demo.dart 5.78 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 12 13 14
enum TabsDemoStyle {
  iconsAndText,
  iconsOnly,
  textOnly
}

Hans Muller's avatar
Hans Muller committed
15
class _Page {
Ian Hickson's avatar
Ian Hickson committed
16
  const _Page({ this.icon, this.text });
Hans Muller's avatar
Hans Muller committed
17 18 19 20
  final IconData icon;
  final String text;
}

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
const List<_Page> _allPages = <_Page>[
  _Page(icon: Icons.grade, text: 'TRIUMPH'),
  _Page(icon: Icons.playlist_add, text: 'NOTE'),
  _Page(icon: Icons.check_circle, text: 'SUCCESS'),
  _Page(icon: Icons.question_answer, text: 'OVERSTATE'),
  _Page(icon: Icons.sentiment_very_satisfied, text: 'SATISFACTION'),
  _Page(icon: Icons.camera, text: 'APERTURE'),
  _Page(icon: Icons.assignment_late, text: 'WE MUST'),
  _Page(icon: Icons.assignment_turned_in, text: 'WE CAN'),
  _Page(icon: Icons.group, text: 'ALL'),
  _Page(icon: Icons.block, text: 'EXCEPT'),
  _Page(icon: Icons.sentiment_very_dissatisfied, text: 'CRYING'),
  _Page(icon: Icons.error, text: 'MISTAKE'),
  _Page(icon: Icons.loop, text: 'TRYING'),
  _Page(icon: Icons.cake, text: 'CAKE'),
Hans Muller's avatar
Hans Muller committed
36 37
];

38
class ScrollableTabsDemo extends StatefulWidget {
39
  static const String routeName = '/material/scrollable-tabs';
40

41
  @override
42
  ScrollableTabsDemoState createState() => ScrollableTabsDemoState();
43 44
}

Hans Muller's avatar
Hans Muller committed
45 46 47
class ScrollableTabsDemoState extends State<ScrollableTabsDemo> with SingleTickerProviderStateMixin {
  TabController _controller;
  TabsDemoStyle _demoStyle = TabsDemoStyle.iconsAndText;
48
  bool _customIndicator = false;
49

Hans Muller's avatar
Hans Muller committed
50 51 52
  @override
  void initState() {
    super.initState();
53
    _controller = TabController(vsync: this, length: _allPages.length);
Hans Muller's avatar
Hans Muller committed
54
  }
55

Hans Muller's avatar
Hans Muller committed
56 57 58 59 60
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
61 62 63 64 65 66 67

  void changeDemoStyle(TabsDemoStyle style) {
    setState(() {
      _demoStyle = style;
    });
  }

68
  Decoration getIndicator() {
69
    if (!_customIndicator)
70
      return const UnderlineTabIndicator();
71 72 73

    switch(_demoStyle) {
      case TabsDemoStyle.iconsAndText:
74
        return ShapeDecoration(
75
          shape: const RoundedRectangleBorder(
76 77
            borderRadius: BorderRadius.all(Radius.circular(4.0)),
            side: BorderSide(
78 79 80 81
              color: Colors.white24,
              width: 2.0,
            ),
          ) + const RoundedRectangleBorder(
82 83
            borderRadius: BorderRadius.all(Radius.circular(4.0)),
            side: BorderSide(
84 85 86 87 88 89 90
              color: Colors.transparent,
              width: 4.0,
            ),
          ),
        );

      case TabsDemoStyle.iconsOnly:
91
        return ShapeDecoration(
92
          shape: const CircleBorder(
93
            side: BorderSide(
94 95 96 97
              color: Colors.white24,
              width: 4.0,
            ),
          ) + const CircleBorder(
98
            side: BorderSide(
99 100 101 102 103 104 105
              color: Colors.transparent,
              width: 4.0,
            ),
          ),
        );

      case TabsDemoStyle.textOnly:
106
        return ShapeDecoration(
107
          shape: const StadiumBorder(
108
            side: BorderSide(
109 110 111 112
              color: Colors.white24,
              width: 2.0,
            ),
          ) + const StadiumBorder(
113
            side: BorderSide(
114 115 116 117 118 119 120 121 122
              color: Colors.transparent,
              width: 4.0,
            ),
          ),
        );
    }
    return null;
  }

123 124 125
  @override
  Widget build(BuildContext context) {
    final Color iconColor = Theme.of(context).accentColor;
126 127
    return Scaffold(
      appBar: AppBar(
128
        title: const Text('Scrollable tabs'),
Hans Muller's avatar
Hans Muller committed
129
        actions: <Widget>[
130
          MaterialDemoDocumentationButton(ScrollableTabsDemo.routeName),
131
          IconButton(
132 133 134 135 136 137 138
            icon: const Icon(Icons.sentiment_very_satisfied),
            onPressed: () {
              setState(() {
                _customIndicator = !_customIndicator;
              });
            },
          ),
139
          PopupMenuButton<TabsDemoStyle>(
Hans Muller's avatar
Hans Muller committed
140 141
            onSelected: changeDemoStyle,
            itemBuilder: (BuildContext context) => <PopupMenuItem<TabsDemoStyle>>[
142
              const PopupMenuItem<TabsDemoStyle>(
Hans Muller's avatar
Hans Muller committed
143
                value: TabsDemoStyle.iconsAndText,
144
                child: Text('Icons and text'),
Hans Muller's avatar
Hans Muller committed
145
              ),
146
              const PopupMenuItem<TabsDemoStyle>(
Hans Muller's avatar
Hans Muller committed
147
                value: TabsDemoStyle.iconsOnly,
148
                child: Text('Icons only'),
Hans Muller's avatar
Hans Muller committed
149
              ),
150
              const PopupMenuItem<TabsDemoStyle>(
Hans Muller's avatar
Hans Muller committed
151
                value: TabsDemoStyle.textOnly,
152
                child: Text('Text only'),
Hans Muller's avatar
Hans Muller committed
153 154 155 156
              ),
            ],
          ),
        ],
157
        bottom: TabBar(
Hans Muller's avatar
Hans Muller committed
158 159
          controller: _controller,
          isScrollable: true,
160
          indicator: getIndicator(),
161 162
          tabs: _allPages.map<Tab>((_Page page) {
            assert(_demoStyle != null);
163
            switch (_demoStyle) {
Hans Muller's avatar
Hans Muller committed
164
              case TabsDemoStyle.iconsAndText:
165
                return Tab(text: page.text, icon: Icon(page.icon));
Hans Muller's avatar
Hans Muller committed
166
              case TabsDemoStyle.iconsOnly:
167
                return Tab(icon: Icon(page.icon));
Hans Muller's avatar
Hans Muller committed
168
              case TabsDemoStyle.textOnly:
169
                return Tab(text: page.text);
Hans Muller's avatar
Hans Muller committed
170
            }
171
            return null;
Hans Muller's avatar
Hans Muller committed
172
          }).toList(),
173
        ),
Hans Muller's avatar
Hans Muller committed
174
      ),
175
      body: TabBarView(
Hans Muller's avatar
Hans Muller committed
176
        controller: _controller,
177
        children: _allPages.map<Widget>((_Page page) {
178
          return SafeArea(
179 180
            top: false,
            bottom: false,
181 182
            child: Container(
              key: ObjectKey(page.icon),
183
              padding: const EdgeInsets.all(12.0),
184 185 186
              child: Card(
                child: Center(
                  child: Icon(
187 188 189
                    page.icon,
                    color: iconColor,
                    size: 128.0,
190
                    semanticLabel: 'Placeholder for ${page.text} tab',
191
                  ),
Hans Muller's avatar
Hans Muller committed
192 193 194 195
                ),
              ),
            ),
          );
196
        }).toList(),
Hans Muller's avatar
Hans Muller committed
197
      ),
198 199 200
    );
  }
}