From 5061076624158b463e8b9c70c60595352bed28d6 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Sat, 5 Mar 2016 00:06:22 -0800 Subject: [PATCH] Try to clarify that you need a Material for an IconButton. Fixes https://github.com/flutter/flutter/issues/2369 --- .../lib/src/material/bottom_sheet.dart | 2 +- .../flutter/lib/src/material/date_picker.dart | 2 ++ packages/flutter/lib/src/material/debug.dart | 17 +++++++++++---- .../flutter/lib/src/material/drawer_item.dart | 2 ++ .../flutter/lib/src/material/icon_button.dart | 2 ++ .../flutter/lib/src/material/ink_well.dart | 21 +++++++++++++++++-- .../flutter/lib/src/material/list_item.dart | 2 ++ packages/flutter/lib/src/material/tabs.dart | 2 ++ 8 files changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/flutter/lib/src/material/bottom_sheet.dart b/packages/flutter/lib/src/material/bottom_sheet.dart index e636a81662..b92e671ba0 100644 --- a/packages/flutter/lib/src/material/bottom_sheet.dart +++ b/packages/flutter/lib/src/material/bottom_sheet.dart @@ -80,7 +80,7 @@ class _BottomSheetState extends State { onVerticalDragUpdate: _handleDragUpdate, onVerticalDragEnd: _handleDragEnd, child: new Material( - key: _childKey, + key: _childKey, child: config.builder(context) ) ); diff --git a/packages/flutter/lib/src/material/date_picker.dart b/packages/flutter/lib/src/material/date_picker.dart index 7b74a93258..85a1f18f67 100644 --- a/packages/flutter/lib/src/material/date_picker.dart +++ b/packages/flutter/lib/src/material/date_picker.dart @@ -10,6 +10,7 @@ import 'package:intl/date_symbols.dart'; import 'package:intl/intl.dart'; import 'colors.dart'; +import 'debug.dart'; import 'ink_well.dart'; import 'theme.dart'; import 'typography.dart'; @@ -403,6 +404,7 @@ class _YearPickerState extends State { } Widget build(BuildContext context) { + assert(debugCheckHasMaterial(context)); return new ScrollableLazyList( itemExtent: _itemExtent, itemCount: config.lastDate.year - config.firstDate.year + 1, diff --git a/packages/flutter/lib/src/material/debug.dart b/packages/flutter/lib/src/material/debug.dart index 45e05c2320..9c081c0364 100644 --- a/packages/flutter/lib/src/material/debug.dart +++ b/packages/flutter/lib/src/material/debug.dart @@ -12,8 +12,15 @@ bool debugCheckHasMaterial(BuildContext context) { if (context.widget is! Material && context.ancestorWidgetOfExactType(Material) == null) { Element element = context; throw new WidgetError( - 'Missing Material widget.', - '${context.widget} needs to be placed inside a Material widget. Ownership chain:\n${element.debugGetOwnershipChain(10)}' + 'No Material widget found.\n' + '${context.widget} widgets require a Material widget ancestor.\n' + 'In material design, most widgets are conceptually "printed" on a sheet of material. In Flutter\'s material library, ' + 'that material is represented by the Material widget. It is the Material widget that renders ink splashes, for instance. ' + 'Because of this, many material library widgets require that there be a Material widget in the tree above them.\n' + 'To introduce a Material widget, you can either directly include one, or use a widget that contains Material itself, ' + 'such as a Card, Dialog, Drawer, or Scaffold.\n' + 'The ownership chain for the affected widget is:\n' + ' ${element.debugGetOwnershipChain(10)}' ); } return true; @@ -27,8 +34,10 @@ bool debugCheckHasScaffold(BuildContext context) { if (Scaffold.of(context) == null) { Element element = context; throw new WidgetError( - 'Missing Scaffold widget.', - '${context.widget} needs to be placed inside the body of a Scaffold widget. Ownership chain:\n${element.debugGetOwnershipChain(10)}' + 'No Scaffold widget found.\n' + '${context.widget} widgets require a Scaffold widget ancestor.\n' + 'The ownership chain for the affected widget is:\n' + ' ${element.debugGetOwnershipChain(10)}' ); } return true; diff --git a/packages/flutter/lib/src/material/drawer_item.dart b/packages/flutter/lib/src/material/drawer_item.dart index 60b63e7d09..8f91ce7ca4 100644 --- a/packages/flutter/lib/src/material/drawer_item.dart +++ b/packages/flutter/lib/src/material/drawer_item.dart @@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart'; import 'colors.dart'; +import 'debug.dart'; import 'icon.dart'; import 'icons.dart'; import 'ink_well.dart'; @@ -55,6 +56,7 @@ class DrawerItem extends StatelessComponent { } Widget build(BuildContext context) { + assert(debugCheckHasMaterial(context)); ThemeData themeData = Theme.of(context); List children = []; diff --git a/packages/flutter/lib/src/material/icon_button.dart b/packages/flutter/lib/src/material/icon_button.dart index 8626974157..83e46e378b 100644 --- a/packages/flutter/lib/src/material/icon_button.dart +++ b/packages/flutter/lib/src/material/icon_button.dart @@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart'; +import 'debug.dart'; import 'icon.dart'; import 'icons.dart'; import 'ink_well.dart'; @@ -53,6 +54,7 @@ class IconButton extends StatelessComponent { final String tooltip; Widget build(BuildContext context) { + assert(debugCheckHasMaterial(context)); Widget result = new Padding( padding: const EdgeDims.all(8.0), child: new Icon( diff --git a/packages/flutter/lib/src/material/ink_well.dart b/packages/flutter/lib/src/material/ink_well.dart index f30ba0d662..50393bdbe3 100644 --- a/packages/flutter/lib/src/material/ink_well.dart +++ b/packages/flutter/lib/src/material/ink_well.dart @@ -12,6 +12,18 @@ import 'debug.dart'; import 'material.dart'; import 'theme.dart'; +/// An area of a Material that responds to touch. Has a configurable shape and +/// can be configured to clip splashes that extend outside its bounds or not. +/// +/// For a variant of this widget that is specialised for rectangular areas that +/// always clip splashes, see [InkWell]. +/// +/// Must have an ancestor [Material] widget in which to cause ink reactions. +/// +/// If a Widget uses this class directly, it should include the following line +/// at the top of its [build] function to call [debugCheckHasMaterial]: +/// +/// assert(debugCheckHasMaterial(context)); class InkResponse extends StatefulComponent { InkResponse({ Key key, @@ -156,9 +168,14 @@ class _InkResponseState extends State { } -/// An area of a Material that responds to touch. +/// A rectangular area of a Material that responds to touch. /// -/// Must have an ancestor Material widget in which to cause ink reactions. +/// Must have an ancestor [Material] widget in which to cause ink reactions. +/// +/// If a Widget uses this class directly, it should include the following line +/// at the top of its [build] function to call [debugCheckHasMaterial]: +/// +/// assert(debugCheckHasMaterial(context)); class InkWell extends InkResponse { InkWell({ Key key, diff --git a/packages/flutter/lib/src/material/list_item.dart b/packages/flutter/lib/src/material/list_item.dart index 549345978e..84d4202ee2 100644 --- a/packages/flutter/lib/src/material/list_item.dart +++ b/packages/flutter/lib/src/material/list_item.dart @@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart'; +import 'debug.dart'; import 'ink_well.dart'; import 'theme.dart'; @@ -85,6 +86,7 @@ class ListItem extends StatelessComponent { } Widget build(BuildContext context) { + assert(debugCheckHasMaterial(context)); final bool isTwoLine = !isThreeLine && secondary != null; final bool isOneLine = !isThreeLine && !isTwoLine; double itemHeight; diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 794c266a31..0c216fd45d 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -10,6 +10,7 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'colors.dart'; +import 'debug.dart'; import 'icon.dart'; import 'icons.dart'; import 'icon_theme.dart'; @@ -330,6 +331,7 @@ class _Tab extends StatelessComponent { } Widget build(BuildContext context) { + assert(debugCheckHasMaterial(context)); Widget labelContent; if (label.icon == null && label.iconBuilder == null) { labelContent = _buildLabelText();