From 82e43099602b9363ab9aae46ac84012af3d6dcfc Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Thu, 4 Feb 2016 12:37:19 -0800 Subject: [PATCH] Support a TabLabel icon Widget builder. --- examples/widgets/fab.dart | 94 --------------------- packages/flutter/lib/src/material/tabs.dart | 47 ++++++----- 2 files changed, 27 insertions(+), 114 deletions(-) delete mode 100644 examples/widgets/fab.dart diff --git a/examples/widgets/fab.dart b/examples/widgets/fab.dart deleted file mode 100644 index 4c3189f1536..00000000000 --- a/examples/widgets/fab.dart +++ /dev/null @@ -1,94 +0,0 @@ -// 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'; - -class _Page { - _Page({this.label, this.color, this.icon}); - final String label; - final Map color; - final String icon; - TabLabel get tabLabel => new TabLabel(text: label); - bool get fabDefined => color != null && icon != null; - Color get fabColor => color[400]; - Icon get fabIcon => new Icon(icon: icon); - Key get fabKey => new ValueKey(fabColor); -} - -List<_Page> _pages = <_Page>[ - new _Page(label: "Blue", color: Colors.indigo, icon: 'content/add'), - new _Page(label: "Too", color: Colors.indigo, icon: 'content/add'), - new _Page(label: "Eco", color: Colors.green, icon: 'content/create'), - new _Page(label: "No"), - new _Page(label: "Teal", color: Colors.teal, icon: 'content/add'), - new _Page(label: "Red", color: Colors.red, icon: 'content/create') -]; - -class FabApp extends StatefulComponent { - FabApp(); - - FabAppState createState() => new FabAppState(); -} - -class FabAppState extends State { - _Page selectedPage = _pages[0]; - void _handleTabSelection(_Page page) { - setState(() { - selectedPage = page; - }); - } - - Widget buildTabView(_Page page) { - return new Builder( - builder: (BuildContext context) { - final TextStyle textStyle = new TextStyle( - color: Theme.of(context).primaryColor, - fontSize: 32.0, - textAlign: TextAlign.center - ); - - return new Container( - key: new ValueKey(page.label), - padding: const EdgeDims.TRBL(48.0, 48.0, 96.0, 48.0), - child: new Card( - child: new Center( - child: new Text(page.label, style: textStyle) - ) - ) - ); - } - ); - } - - Widget build(BuildContext context) { - return new TabBarSelection<_Page>( - values: _pages, - onChanged: _handleTabSelection, - child: new Scaffold( - toolBar: new ToolBar( - elevation: 0, - center: new Text('FAB Transition Demo'), - tabBar: new TabBar( - labels: new Map.fromIterable(_pages, value: (_Page page) => page.tabLabel) - ) - ), - body: new TabBarView(children: _pages.map(buildTabView).toList()), - floatingActionButton: !selectedPage.fabDefined ? null : new FloatingActionButton( - key: selectedPage.fabKey, - backgroundColor: selectedPage.fabColor, - child: selectedPage.fabIcon - ) - ) - ); - } -} - -void main() { - runApp(new MaterialApp( - title: 'FabApp', - routes: { - '/': (RouteArguments args) => new FabApp() - } - )); -} diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 939403e9df7..6e7269af02a 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -280,21 +280,19 @@ class _TabBarWrapper extends MultiChildRenderObjectWidget { } } +typedef Widget TabLabelIconBuilder(BuildContext context, Color color); + +/// Each TabBar tab can display either a title [text], an icon, or both. An icon +/// can be specified by either the icon or iconBuilder parameters. In either case +/// the icon will occupy a 24x24 box above the title text. If iconBuilder is +/// specified its color parameter is the color that an ordinary icon would have +/// been drawn with. The color reflects that tab's selection state. class TabLabel { - const TabLabel({ this.text, this.icon }); + const TabLabel({ this.text, this.icon, this.iconBuilder }); final String text; final String icon; - - String toString() { - if (text != null && icon != null) - return '"$text" ($icon)'; - if (text != null) - return '"$text"'; - if (icon != null) - return '$icon'; - return 'EMPTY TAB LABEL'; - } + final TabLabelIconBuilder iconBuilder; } class _Tab extends StatelessComponent { @@ -304,7 +302,7 @@ class _Tab extends StatelessComponent { this.label, this.color }) : super(key: key) { - assert(label.text != null || label.icon != null); + assert(label.text != null || label.icon != null || label.iconBuilder != null); } final VoidCallback onSelected; @@ -317,22 +315,30 @@ class _Tab extends StatelessComponent { return new Text(label.text, style: style); } - Widget _buildLabelIcon() { - assert(label.icon != null); - return new Icon(icon: label.icon, color: color); + Widget _buildLabelIcon(BuildContext context) { + assert(label.icon != null || label.iconBuilder != null); + if (label.icon != null) { + return new Icon(icon: label.icon, color: color); + } else { + return new SizedBox( + width: 24.0, + height: 24.0, + child: label.iconBuilder(context, color) + ); + } } Widget build(BuildContext context) { Widget labelContent; - if (label.icon == null) { + if (label.icon == null && label.iconBuilder == null) { labelContent = _buildLabelText(); } else if (label.text == null) { - labelContent = _buildLabelIcon(); + labelContent = _buildLabelIcon(context); } else { labelContent = new Column( children: [ new Container( - child: _buildLabelIcon(), + child: _buildLabelIcon(context), margin: const EdgeDims.only(bottom: 10.0) ), _buildLabelText() @@ -733,13 +739,14 @@ class _TabBarState extends ScrollableState> implements TabBarSelect TextStyle textStyle = themeData.primaryTextTheme.body1; IconThemeData iconTheme = themeData.primaryIconTheme; + Color textColor = themeData.primaryTextTheme.body1.color.withAlpha(0xB2); // 70% alpha List tabs = []; bool textAndIcons = false; int tabIndex = 0; for (TabLabel label in config.labels.values) { - tabs.add(_toTab(label, tabIndex++, textStyle.color, indicatorColor)); - if (label.text != null && label.icon != null) + tabs.add(_toTab(label, tabIndex++, textColor, indicatorColor)); + if (label.text != null && (label.icon != null || label.iconBuilder != null)) textAndIcons = true; }