Icon should use an enum rather than an int for size

Material design icons are defined to work at specific sizes: 18, 24, 36, 48.
The current API doesn't reflect that and just takes a size int. If an invalid
size is chosen an error is printed to the console and no icon shows up.

Fixes #1816
diff --git a/examples/address_book/lib/main.dart b/examples/address_book/lib/main.dart
index ab9372c..4394946 100644
--- a/examples/address_book/lib/main.dart
+++ b/examples/address_book/lib/main.dart
@@ -20,7 +20,7 @@
     return new Row(<Widget>[
         new Padding(
           padding: const EdgeDims.symmetric(horizontal: 16.0),
-          child: new Icon(type: icon, size: 24)
+          child: new Icon(type: icon)
         ),
         new Flexible(
           child: new Input(
@@ -43,7 +43,7 @@
 
   Widget buildFloatingActionButton(BuildContext context) {
     return new FloatingActionButton(
-      child: new Icon(type: 'image/photo_camera', size: 24),
+      child: new Icon(type: 'image/photo_camera'),
       backgroundColor: Theme.of(context).accentColor
     );
   }
diff --git a/examples/fitness/lib/feed.dart b/examples/fitness/lib/feed.dart
index 5adc86a..fa15bf5 100644
--- a/examples/fitness/lib/feed.dart
+++ b/examples/fitness/lib/feed.dart
@@ -200,7 +200,7 @@
     switch (_fitnessMode) {
       case FitnessMode.feed:
         return new FloatingActionButton(
-          child: new Icon(type: 'content/add', size: 24),
+          child: new Icon(type: 'content/add'),
           onPressed: _handleActionButtonPressed
         );
       case FitnessMode.chart:
diff --git a/examples/stocks/lib/stock_home.dart b/examples/stocks/lib/stock_home.dart
index 0085a93..9e1fa4a 100644
--- a/examples/stocks/lib/stock_home.dart
+++ b/examples/stocks/lib/stock_home.dart
@@ -254,7 +254,7 @@
 
   Widget buildFloatingActionButton() {
     return new FloatingActionButton(
-      child: new Icon(type: 'content/add', size: 24),
+      child: new Icon(type: 'content/add'),
       backgroundColor: Colors.redAccent[200],
       onPressed: _handleStockPurchased
     );
diff --git a/examples/stocks/lib/stock_menu.dart b/examples/stocks/lib/stock_menu.dart
index 68c9f4d..f58ab32 100644
--- a/examples/stocks/lib/stock_menu.dart
+++ b/examples/stocks/lib/stock_menu.dart
@@ -63,7 +63,7 @@
               child: new Row(<Widget>[
                 new Icon(
                   type: 'device/dvr',
-                  size: 18
+                  size: IconSize.s18
                 ),
                 new Container(
                   width: 8.0
diff --git a/examples/widgets/card_collection.dart b/examples/widgets/card_collection.dart
index 32af1b1..beda837 100644
--- a/examples/widgets/card_collection.dart
+++ b/examples/widgets/card_collection.dart
@@ -289,7 +289,7 @@
         child: new Container(
           height: cardModel.height,
           padding: const EdgeDims.all(8.0),
-          child: _editable ? 
+          child: _editable ?
             new Center(
               child: new Input(
                 key: new GlobalObjectKey(cardModel),
@@ -329,11 +329,11 @@
         backgroundMessage = "Unsupported dismissDirection";
     }
 
-    Widget leftArrowIcon =  new Icon(type: 'navigation/arrow_back', size: 36);
+    Widget leftArrowIcon =  new Icon(type: 'navigation/arrow_back', size: IconSize.s36);
     if (_dismissDirection == DismissDirection.right)
       leftArrowIcon = new Opacity(opacity: 0.1, child: leftArrowIcon);
 
-    Widget rightArrowIcon =  new Icon(type: 'navigation/arrow_forward', size: 36);
+    Widget rightArrowIcon =  new Icon(type: 'navigation/arrow_forward', size: IconSize.s36);
     if (_dismissDirection == DismissDirection.left)
       rightArrowIcon = new Opacity(opacity: 0.1, child: rightArrowIcon);
 
diff --git a/sky/packages/sky/lib/src/material/drawer_item.dart b/sky/packages/sky/lib/src/material/drawer_item.dart
index 5c6614b..bc4d431 100644
--- a/sky/packages/sky/lib/src/material/drawer_item.dart
+++ b/sky/packages/sky/lib/src/material/drawer_item.dart
@@ -49,7 +49,6 @@
           padding: const EdgeDims.symmetric(horizontal: 16.0),
           child: new Icon(
             type: icon,
-            size: 24,
             colorFilter: _getColorFilter(themeData)
           )
         )
diff --git a/sky/packages/sky/lib/src/material/dropdown.dart b/sky/packages/sky/lib/src/material/dropdown.dart
index b8b89f3..b705110 100644
--- a/sky/packages/sky/lib/src/material/dropdown.dart
+++ b/sky/packages/sky/lib/src/material/dropdown.dart
@@ -244,7 +244,7 @@
               alignment: const FractionalOffset(0.5, 0.0)
             ),
             new Container(
-              child: new Icon(type: 'navigation/arrow_drop_down', size: 36),
+              child: new Icon(type: 'navigation/arrow_drop_down', size: IconSize.s36),
               padding: const EdgeDims.only(top: 6.0)
             )
           ])
diff --git a/sky/packages/sky/lib/src/material/icon.dart b/sky/packages/sky/lib/src/material/icon.dart
index e5e47b4..1188145 100644
--- a/sky/packages/sky/lib/src/material/icon.dart
+++ b/sky/packages/sky/lib/src/material/icon.dart
@@ -8,10 +8,24 @@
 import 'icon_theme.dart';
 import 'icon_theme_data.dart';
 
+enum IconSize {
+  s18,
+  s24,
+  s36,
+  s48,
+}
+
+const Map<IconSize, int> _kIconSize = const <IconSize, int>{
+  IconSize.s18: 18,
+  IconSize.s24: 24,
+  IconSize.s36: 36,
+  IconSize.s48: 48,
+};
+
 class Icon extends StatelessComponent {
   Icon({
     Key key,
-    this.size,
+    this.size: IconSize.s24,
     this.type: '',
     this.color,
     this.colorFilter
@@ -20,7 +34,7 @@
     assert(type != null);
   }
 
-  final int size;
+  final IconSize size;
   final String type;
   final IconThemeColor color;
   final ColorFilter colorFilter;
@@ -55,10 +69,11 @@
     // Should we use the ios images on ios?
     String density = 'drawable-xxhdpi';
     String colorSuffix = _getColorSuffix(context);
+    int iconSize = _kIconSize[size];
     return new AssetImage(
-      name: '$category/$density/ic_${subtype}_${colorSuffix}_${size}dp.png',
-      width: size.toDouble(),
-      height: size.toDouble(),
+      name: '$category/$density/ic_${subtype}_${colorSuffix}_${iconSize}dp.png',
+      width: iconSize.toDouble(),
+      height: iconSize.toDouble(),
       colorFilter: colorFilter
     );
   }
diff --git a/sky/packages/sky/lib/src/material/icon_button.dart b/sky/packages/sky/lib/src/material/icon_button.dart
index 0370a59..eb78d31 100644
--- a/sky/packages/sky/lib/src/material/icon_button.dart
+++ b/sky/packages/sky/lib/src/material/icon_button.dart
@@ -28,7 +28,6 @@
         padding: const EdgeDims.all(8.0),
         child: new Icon(
           type: icon,
-          size: 24,
           color: color,
           colorFilter: colorFilter
         )
diff --git a/sky/packages/sky/lib/src/material/tabs.dart b/sky/packages/sky/lib/src/material/tabs.dart
index 0134165..01c6499 100644
--- a/sky/packages/sky/lib/src/material/tabs.dart
+++ b/sky/packages/sky/lib/src/material/tabs.dart
@@ -27,7 +27,6 @@
 const double _kMinTabWidth = 72.0;
 const double _kMaxTabWidth = 264.0;
 const EdgeDims _kTabLabelPadding = const EdgeDims.symmetric(horizontal: 12.0);
-const int _kTabIconSize = 24;
 const double _kTabBarScrollDrag = 0.025;
 const Duration _kTabBarScroll = const Duration(milliseconds: 200);
 
@@ -321,7 +320,7 @@
     assert(label.icon != null);
     Color iconColor = selected ? selectedColor : color;
     ColorFilter filter = new ColorFilter.mode(iconColor, TransferMode.srcATop);
-    return new Icon(type: label.icon, size: _kTabIconSize, colorFilter: filter);
+    return new Icon(type: label.icon, colorFilter: filter);
   }
 
   Widget build(BuildContext context) {