[Material] Update slider and slider theme with new sizes, shapes, and color mappings (#30390)

This PR makes a number of changes to the visual appearance of material sliders:

Sizes/Shapes
** enabled thumb radius from 6 to 10
** disabled thumb radius from 4 to 10 with no gap
** default track shape is a rounded rect rather than a rect
**
Colors
** all of the colors now use the new color scheme
** overlay opacity has been reduce from 16% to 12%
** value indicator text color now respects the indicator it is on by using onPrimary
** disabledThumb color no respects the surface it is on by using onSurface
The slider theme is also now constructed consistently with other theme objects within the ThemeData. By default, all values are null, and have default values that are resolved in the slider itself, rather than in the slider theme.
diff --git a/packages/flutter/lib/src/material/slider.dart b/packages/flutter/lib/src/material/slider.dart
index 32da622..03bbea4 100644
--- a/packages/flutter/lib/src/material/slider.dart
+++ b/packages/flutter/lib/src/material/slider.dart
@@ -428,27 +428,52 @@
     return widget.max > widget.min ? (value - widget.min) / (widget.max - widget.min) : 0.0;
   }
 
+  static const double _defaultTrackHeight = 2;
+  static const SliderTrackShape _defaultTrackShape = RoundedRectSliderTrackShape();
+  static const SliderTickMarkShape _defaultTickMarkShape = RoundSliderTickMarkShape();
+  static const SliderComponentShape _defaultOverlayShape = RoundSliderOverlayShape();
+  static const SliderComponentShape _defaultThumbShape = RoundSliderThumbShape();
+  static const SliderComponentShape _defaultValueIndicatorShape = PaddleSliderValueIndicatorShape();
+  static const ShowValueIndicator _defaultShowValueIndicator = ShowValueIndicator.onlyForDiscrete;
+
   @override
   Widget build(BuildContext context) {
     assert(debugCheckHasMaterial(context));
     assert(debugCheckHasMediaQuery(context));
 
+    final ThemeData theme = Theme.of(context);
     SliderThemeData sliderTheme = SliderTheme.of(context);
 
     // If the widget has active or inactive colors specified, then we plug them
     // in to the slider theme as best we can. If the developer wants more
-    // control than that, then they need to use a SliderTheme.
-    if (widget.activeColor != null || widget.inactiveColor != null) {
-      sliderTheme = sliderTheme.copyWith(
-        activeTrackColor: widget.activeColor,
-        inactiveTrackColor: widget.inactiveColor,
-        activeTickMarkColor: widget.inactiveColor,
-        inactiveTickMarkColor: widget.activeColor,
-        thumbColor: widget.activeColor,
-        valueIndicatorColor: widget.activeColor,
-        overlayColor: widget.activeColor?.withAlpha(0x29),
-      );
-    }
+    // control than that, then they need to use a SliderTheme. The default
+    // colors come from the ThemeData.colorScheme. These colors, along with
+    // the default shapes and text styles are aligned to the Material
+    // Guidelines.
+    sliderTheme = sliderTheme.copyWith(
+      trackHeight: sliderTheme.trackHeight ?? _defaultTrackHeight,
+      activeTrackColor: widget.activeColor ?? sliderTheme.activeTrackColor ?? theme.colorScheme.primary,
+      inactiveTrackColor: widget.inactiveColor ?? sliderTheme.inactiveTrackColor ?? theme.colorScheme.primary.withOpacity(0.24),
+      disabledActiveTrackColor: sliderTheme.disabledActiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.32),
+      disabledInactiveTrackColor: sliderTheme.disabledInactiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.12),
+      activeTickMarkColor: widget.inactiveColor ?? sliderTheme.activeTickMarkColor ?? theme.colorScheme.onPrimary.withOpacity(0.54),
+      inactiveTickMarkColor: widget.activeColor ?? sliderTheme.inactiveTickMarkColor ?? theme.colorScheme.primary.withOpacity(0.54),
+      disabledActiveTickMarkColor: sliderTheme.disabledActiveTickMarkColor ?? theme.colorScheme.onPrimary.withOpacity(0.12),
+      disabledInactiveTickMarkColor: sliderTheme.disabledInactiveTickMarkColor ?? theme.colorScheme.onSurface.withOpacity(0.12),
+      thumbColor: widget.activeColor ?? sliderTheme.thumbColor ?? theme.colorScheme.primary,
+      disabledThumbColor: sliderTheme.disabledThumbColor ?? theme.colorScheme.onSurface.withOpacity(0.38),
+      overlayColor: widget.activeColor?.withOpacity(0.12) ?? sliderTheme.overlayColor ?? theme.colorScheme.primary.withOpacity(0.12),
+      valueIndicatorColor: widget.activeColor ?? sliderTheme.valueIndicatorColor ?? theme.colorScheme.primary,
+      trackShape: sliderTheme.trackShape ?? _defaultTrackShape,
+      tickMarkShape: sliderTheme.tickMarkShape ?? _defaultTickMarkShape,
+      thumbShape: sliderTheme.thumbShape ?? _defaultThumbShape,
+      overlayShape: sliderTheme.overlayShape ?? _defaultOverlayShape,
+      valueIndicatorShape: sliderTheme.valueIndicatorShape ?? _defaultValueIndicatorShape,
+      showValueIndicator: sliderTheme.showValueIndicator ?? _defaultShowValueIndicator,
+      valueIndicatorTextStyle: sliderTheme.valueIndicatorTextStyle ?? theme.textTheme.body2.copyWith(
+        color: theme.colorScheme.onPrimary,
+      ),
+    );
 
     return _SliderRenderObjectWidget(
       value: _unlerp(widget.value),
@@ -498,7 +523,6 @@
       divisions: divisions,
       label: label,
       sliderTheme: sliderTheme,
-      theme: Theme.of(context),
       mediaQueryData: mediaQueryData,
       onChanged: onChanged,
       onChangeStart: onChangeStart,
@@ -536,7 +560,6 @@
     int divisions,
     String label,
     SliderThemeData sliderTheme,
-    ThemeData theme,
     MediaQueryData mediaQueryData,
     TargetPlatform platform,
     ValueChanged<double> onChanged,
@@ -554,7 +577,6 @@
        _value = value,
        _divisions = divisions,
        _sliderTheme = sliderTheme,
-       _theme = theme,
        _mediaQueryData = mediaQueryData,
        _onChanged = onChanged,
        _state = state,
@@ -983,7 +1005,6 @@
       isEnabled: isInteractive,
     );
 
-    // TODO(closkmith): Move this to paint after the thumb.
     if (!_overlayAnimation.isDismissed) {
       _sliderTheme.overlayShape.paint(
         context,
@@ -1000,7 +1021,6 @@
     }
 
     if (isDiscrete) {
-      // TODO(clocksmith): Align tick mark centers to ends of track by not subtracting diameter from length.
       final double tickMarkWidth = _sliderTheme.tickMarkShape.getPreferredSize(
         isEnabled: isInteractive,
         sliderTheme: _sliderTheme,
diff --git a/packages/flutter/lib/src/material/slider_theme.dart b/packages/flutter/lib/src/material/slider_theme.dart
index 205b5d3..88ff1dd 100644
--- a/packages/flutter/lib/src/material/slider_theme.dart
+++ b/packages/flutter/lib/src/material/slider_theme.dart
@@ -210,46 +210,27 @@
   /// ```
   /// {@end-tool}
   const SliderThemeData({
-    @required this.trackHeight,
-    @required this.activeTrackColor,
-    @required this.inactiveTrackColor,
-    @required this.disabledActiveTrackColor,
-    @required this.disabledInactiveTrackColor,
-    @required this.activeTickMarkColor,
-    @required this.inactiveTickMarkColor,
-    @required this.disabledActiveTickMarkColor,
-    @required this.disabledInactiveTickMarkColor,
-    @required this.thumbColor,
-    @required this.disabledThumbColor,
-    @required this.overlayColor,
-    @required this.valueIndicatorColor,
-    @required this.trackShape,
-    @required this.tickMarkShape,
-    @required this.thumbShape,
-    @required this.overlayShape,
-    @required this.valueIndicatorShape,
-    @required this.showValueIndicator,
-    @required this.valueIndicatorTextStyle,
-  }) : assert(trackHeight != null),
-       assert(activeTrackColor != null),
-       assert(inactiveTrackColor != null),
-       assert(disabledActiveTrackColor != null),
-       assert(disabledInactiveTrackColor != null),
-       assert(activeTickMarkColor != null),
-       assert(inactiveTickMarkColor != null),
-       assert(disabledActiveTickMarkColor != null),
-       assert(disabledInactiveTickMarkColor != null),
-       assert(thumbColor != null),
-       assert(disabledThumbColor != null),
-       assert(overlayColor != null),
-       assert(valueIndicatorColor != null),
-       assert(trackShape != null),
-       assert(tickMarkShape != null),
-       assert(thumbShape != null),
-       assert(overlayShape != null),
-       assert(valueIndicatorShape != null),
-       assert(valueIndicatorTextStyle != null),
-       assert(showValueIndicator != null);
+    this.trackHeight,
+    this.activeTrackColor,
+    this.inactiveTrackColor,
+    this.disabledActiveTrackColor,
+    this.disabledInactiveTrackColor,
+    this.activeTickMarkColor,
+    this.inactiveTickMarkColor,
+    this.disabledActiveTickMarkColor,
+    this.disabledInactiveTickMarkColor,
+    this.thumbColor,
+    this.disabledThumbColor,
+    this.overlayColor,
+    this.valueIndicatorColor,
+    this.trackShape,
+    this.tickMarkShape,
+    this.thumbShape,
+    this.overlayShape,
+    this.valueIndicatorShape,
+    this.showValueIndicator,
+    this.valueIndicatorTextStyle,
+  });
 
   /// Generates a SliderThemeData from three main colors.
   ///
@@ -283,15 +264,9 @@
     const int disabledInactiveTickMarkAlpha = 0x1f; // 12% opacity
     const int thumbAlpha = 0xff;
     const int disabledThumbAlpha = 0x52; // 32% opacity
+    const int overlayAlpha = 0x1f; // 12% opacity
     const int valueIndicatorAlpha = 0xff;
 
-    // TODO(gspencer): We don't really follow the spec here for overlays.
-    // The spec says to use 16% opacity for drawing over light material,
-    // and 32% for colored material, but we don't really have a way to
-    // know what the underlying color is, so there's no easy way to
-    // implement this. Choosing the "light" version for now.
-    const int overlayLightAlpha = 0x29; // 16% opacity
-
     return SliderThemeData(
       trackHeight: 2.0,
       activeTrackColor: primaryColor.withAlpha(activeTrackAlpha),
@@ -304,9 +279,9 @@
       disabledInactiveTickMarkColor: primaryColorDark.withAlpha(disabledInactiveTickMarkAlpha),
       thumbColor: primaryColor.withAlpha(thumbAlpha),
       disabledThumbColor: primaryColorDark.withAlpha(disabledThumbAlpha),
-      overlayColor: primaryColor.withAlpha(overlayLightAlpha),
+      overlayColor: primaryColor.withAlpha(overlayAlpha),
       valueIndicatorColor: primaryColor.withAlpha(valueIndicatorAlpha),
-      trackShape: const RectangularSliderTrackShape(),
+      trackShape: const RoundedRectSliderTrackShape(),
       tickMarkShape: const RoundSliderTickMarkShape(),
       thumbShape: const RoundSliderThumbShape(),
       overlayShape: const RoundSliderOverlayShape(),
@@ -927,15 +902,151 @@
   }
 }
 
-// The following shapes are the material defaults.
+/// Base track shape that provides an implementation of [getPreferredRect] for
+/// default sizing.
+///
+/// See also:
+///
+/// * [RectangularSliderTrackShape], which is a track shape with sharp
+/// rectangular edges
+/// * [RoundedRectSliderTrackShape], which is a track shape with round
+/// stadium-like edges.
+///
+/// The height is set from [SliderThemeData.trackHeight] and the width of the
+/// parent box less the larger of the widths of [SliderThemeData.thumbShape] and
+/// [SliderThemeData.overlayShape].
+abstract class BaseSliderTrackShape {
+  /// Returns a rect that represents the track bounds that fits within the
+  /// [Slider].
+  ///
+  /// The width is the width of the [Slider], but padded by the max
+  /// of the overlay and thumb radius. The height is defined by the
+  /// [SliderThemeData.trackHeight].
+  ///
+  /// The [Rect] is centered both horizontally and vertically within the slider
+  /// bounds.
+  Rect getPreferredRect({
+    @required RenderBox parentBox,
+    Offset offset = Offset.zero,
+    SliderThemeData sliderTheme,
+    bool isEnabled = false,
+    bool isDiscrete = false,
+  }) {
+    assert(parentBox != null);
+    final double thumbWidth = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete).width;
+    final double overlayWidth = sliderTheme.overlayShape.getPreferredSize(isEnabled, isDiscrete).width;
+    final double trackHeight = sliderTheme.trackHeight;
+    assert(overlayWidth >= 0);
+    assert(trackHeight >= 0);
+    assert(parentBox.size.width >= overlayWidth);
+    assert(parentBox.size.height >= trackHeight);
+
+    final double trackLeft = offset.dx + overlayWidth / 2;
+    final double trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2;
+    final double trackWidth = parentBox.size.width - math.max(thumbWidth, overlayWidth);
+    return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
+  }
+}
 
 /// This is the default shape of a [Slider]'s track.
 ///
+/// It paints a solid colored rectangle with rounded edges, vertically centered
+/// in the [parentBox]. The track rectangle extends to the bounds of the
+/// [parentBox], but is padded by the larger of [RoundSliderOverlayShape]'s
+/// radius and [RoundSliderThumbShape]'s radius. The height is defined by the
+/// [SliderThemeData.trackHeight]. The color is determined by the [Slider]'s
+/// enabled state and the track segment's active state which are defined by:
+///   [SliderThemeData.activeTrackColor],
+///   [SliderThemeData.inactiveTrackColor],
+///   [SliderThemeData.disabledActiveTrackColor],
+///   [SliderThemeData.disabledInactiveTrackColor].
+///
+/// See also:
+///
+///  * [Slider], for the component that is meant to display this shape.
+///  * [SliderThemeData], where an instance of this class is set to inform the
+///    slider of the visual details of the its track.
+///  * [SliderTrackShape], which is the base component for creating other
+///    custom track shapes.
+///  * [RectangularSliderTrackShape], for a similar track with sharp edges.
+class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackShape {
+  /// Create a slider track that draws two rectangles with rounded outer edges.
+  const RoundedRectSliderTrackShape();
+
+  @override
+  void paint(
+    PaintingContext context,
+    Offset offset, {
+    @required RenderBox parentBox,
+    @required SliderThemeData sliderTheme,
+    @required Animation<double> enableAnimation,
+    @required TextDirection textDirection,
+    @required Offset thumbCenter,
+    bool isDiscrete = false,
+    bool isEnabled = false,
+  }) {
+    assert(context != null);
+    assert(offset != null);
+    assert(parentBox != null);
+    assert(sliderTheme != null);
+    assert(enableAnimation != null);
+    assert(textDirection != null);
+    assert(thumbCenter != null);
+    // If the slider track height is less than or equal to 0, then it makes no
+    // difference whether the track is painted or not, therefore the painting
+    // can be a no-op.
+    if (sliderTheme.trackHeight <= 0) {
+      return;
+    }
+
+    // Assign the track segment paints, which are leading: active and
+    // trailing: inactive.
+    final ColorTween activeTrackColorTween = ColorTween(begin: sliderTheme.disabledActiveTrackColor, end: sliderTheme.activeTrackColor);
+    final ColorTween inactiveTrackColorTween = ColorTween(begin: sliderTheme.disabledInactiveTrackColor, end: sliderTheme.inactiveTrackColor);
+    final Paint activePaint = Paint()..color = activeTrackColorTween.evaluate(enableAnimation);
+    final Paint inactivePaint = Paint()..color = inactiveTrackColorTween.evaluate(enableAnimation);
+    Paint leftTrackPaint;
+    Paint rightTrackPaint;
+    switch (textDirection) {
+      case TextDirection.ltr:
+        leftTrackPaint = activePaint;
+        rightTrackPaint = inactivePaint;
+        break;
+      case TextDirection.rtl:
+        leftTrackPaint = inactivePaint;
+        rightTrackPaint = activePaint;
+        break;
+    }
+
+    final Rect trackRect = getPreferredRect(
+      parentBox: parentBox,
+      offset: offset,
+      sliderTheme: sliderTheme,
+      isEnabled: isEnabled,
+      isDiscrete: isDiscrete,
+    );
+
+    // The arc rects create a semi-circle with radius equal to track height.
+    final Rect leftTrackArcRect = Rect.fromLTWH(trackRect.left, trackRect.top, trackRect.height, trackRect.height);
+    context.canvas.drawArc(leftTrackArcRect, math.pi / 2, math.pi, false, leftTrackPaint);
+    final Rect rightTrackArcRect = Rect.fromLTWH(trackRect.right - trackRect.height / 2, trackRect.top, trackRect.height, trackRect.height);
+    context.canvas.drawArc(rightTrackArcRect, -math.pi / 2, math.pi, false, rightTrackPaint);
+
+    final Size thumbSize = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete);
+    final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left + trackRect.height / 2, trackRect.top, thumbCenter.dx - thumbSize.width / 2, trackRect.bottom);
+    context.canvas.drawRect(leftTrackSegment, leftTrackPaint);
+    final Rect rightTrackSegment = Rect.fromLTRB(thumbCenter.dx + thumbSize.width / 2, trackRect.top, trackRect.right, trackRect.bottom);
+    context.canvas.drawRect(rightTrackSegment, rightTrackPaint);
+  }
+}
+
+/// A [Slider] track that's a simple rectangle.
+///
 /// It paints a solid colored rectangle, vertically centered in the
 /// [parentBox]. The track rectangle extends to the bounds of the [parentBox],
 /// but is padded by the [RoundSliderOverlayShape] radius. The height is defined
 /// by the [SliderThemeData.trackHeight]. The color is determined by the
-/// [Slider]'s enabled state and the track piece's active state which are
+/// [Slider]'s enabled state and the track segments's active state which are
 /// defined by:
 ///   [SliderThemeData.activeTrackColor],
 ///   [SliderThemeData.inactiveTrackColor],
@@ -944,11 +1055,12 @@
 ///
 /// See also:
 ///
-///  * [Slider] for the component that this is meant to display this shape.
-///  * [SliderThemeData] where an instance of this class is set to inform the
+///  * [Slider], for the component that is meant to display this shape.
+///  * [SliderThemeData], where an instance of this class is set to inform the
 ///    slider of the visual details of the its track.
-///  * [SliderTrackShape] Base component for creating other custom track
-///    shapes.
+///  * [SliderTrackShape], which is the base component for creating other
+///     custom track shapes.
+///  * [RoundedRectSliderTrackShape], for a similar track with rounded edges.
 class RectangularSliderTrackShape extends SliderTrackShape {
   /// Create a slider track that draws 2 rectangles.
   const RectangularSliderTrackShape({ this.disabledThumbGapWidth = 2.0 });
@@ -963,12 +1075,15 @@
 
   @override
   Rect getPreferredRect({
-    RenderBox parentBox,
+    @required RenderBox parentBox,
     Offset offset = Offset.zero,
-    SliderThemeData sliderTheme,
-    bool isEnabled,
-    bool isDiscrete,
+    @required SliderThemeData sliderTheme,
+    bool isEnabled = false,
+    bool isDiscrete = false,
   }) {
+    assert(parentBox != null);
+    assert(sliderTheme != null);
+    final double thumbWidth = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete).width;
     final double overlayWidth = sliderTheme.overlayShape.getPreferredSize(isEnabled, isDiscrete).width;
     final double trackHeight = sliderTheme.trackHeight;
     assert(overlayWidth >= 0);
@@ -978,29 +1093,33 @@
 
     final double trackLeft = offset.dx + overlayWidth / 2;
     final double trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2;
-    // TODO(clocksmith): Although this works for a material, perhaps the default
-    // rectangular track should be padded not just by the overlay, but by the
-    // max of the thumb and the overlay, in case there is no overlay.
-    final double trackWidth = parentBox.size.width - overlayWidth;
+    final double trackWidth = parentBox.size.width - math.max(thumbWidth, overlayWidth);
     return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
   }
 
-
   @override
   void paint(
     PaintingContext context,
     Offset offset, {
-    RenderBox parentBox,
-    SliderThemeData sliderTheme,
-    Animation<double> enableAnimation,
-    TextDirection textDirection,
-    Offset thumbCenter,
-    bool isDiscrete,
-    bool isEnabled,
+    @required RenderBox parentBox,
+    @required SliderThemeData sliderTheme,
+    @required Animation<double> enableAnimation,
+    @required TextDirection textDirection,
+    @required Offset thumbCenter,
+    bool isDiscrete = false,
+    bool isEnabled = false,
   }) {
-    // If the slider track height is 0, then it makes no difference whether the
-    // track is painted or not, therefore the painting can be a no-op.
-    if (sliderTheme.trackHeight == 0) {
+    assert(context != null);
+    assert(offset != null);
+    assert(parentBox != null);
+    assert(sliderTheme != null);
+    assert(enableAnimation != null);
+    assert(textDirection != null);
+    assert(thumbCenter != null);
+    // If the slider track height is less than or equal to 0, then it makes no
+    // difference whether the track is painted or not, therefore the painting
+    // can be a no-op.
+    if (sliderTheme.trackHeight <= 0) {
       return;
     }
 
@@ -1023,28 +1142,17 @@
         break;
     }
 
-    // Used to create a gap around the thumb iff the slider is disabled.
-    // If the slider is enabled, the track can be drawn beneath the thumb
-    // without a gap. But when the slider is disabled, the track is shortened
-    // and this gap helps determine how much shorter it should be.
-    // TODO(clocksmith): The new Material spec has a gray circle in place of this gap.
-    double horizontalAdjustment = 0.0;
-    if (!isEnabled) {
-      final double disabledThumbRadius = sliderTheme.thumbShape.getPreferredSize(false, isDiscrete).width / 2.0;
-      final double gap = disabledThumbGapWidth * (1.0 - enableAnimation.value);
-      horizontalAdjustment = disabledThumbRadius + gap;
-    }
-
     final Rect trackRect = getPreferredRect(
-        parentBox: parentBox,
-        offset: offset,
-        sliderTheme: sliderTheme,
-        isEnabled: isEnabled,
-        isDiscrete: isDiscrete,
+      parentBox: parentBox,
+      offset: offset,
+      sliderTheme: sliderTheme,
+      isEnabled: isEnabled,
+      isDiscrete: isDiscrete,
     );
-    final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left, trackRect.top, thumbCenter.dx - horizontalAdjustment, trackRect.bottom);
+
+    final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left, trackRect.top, thumbCenter.dx, trackRect.bottom);
     context.canvas.drawRect(leftTrackSegment, leftTrackPaint);
-    final Rect rightTrackSegment = Rect.fromLTRB(thumbCenter.dx + horizontalAdjustment, trackRect.top, trackRect.right, trackRect.bottom);
+    final Rect rightTrackSegment = Rect.fromLTRB(thumbCenter.dx, trackRect.top, trackRect.right, trackRect.bottom);
     context.canvas.drawRect(rightTrackSegment, rightTrackPaint);
   }
 }
@@ -1090,13 +1198,20 @@
   void paint(
     PaintingContext context,
     Offset center, {
-    RenderBox parentBox,
-    SliderThemeData sliderTheme,
-    Animation<double> enableAnimation,
-    TextDirection textDirection,
-    Offset thumbCenter,
-    bool isEnabled,
+    @required RenderBox parentBox,
+    @required SliderThemeData sliderTheme,
+    @required Animation<double> enableAnimation,
+    @required TextDirection textDirection,
+    @required Offset thumbCenter,
+    bool isEnabled = false,
   }) {
+    assert(context != null);
+    assert(center != null);
+    assert(parentBox != null);
+    assert(sliderTheme != null);
+    assert(enableAnimation != null);
+    assert(textDirection != null);
+    assert(thumbCenter != null);
     // The paint color of the tick mark depends on its position relative
     // to the thumb and the text direction.
     Color begin;
@@ -1133,26 +1248,22 @@
 ///    sliders in a widget subtree.
 class RoundSliderThumbShape extends SliderComponentShape {
   /// Create a slider thumb that draws a circle.
-  // TODO(clocksmith): This needs to be changed to 10 according to spec.
   const RoundSliderThumbShape({
-    this.enabledThumbRadius = 6.0,
+    this.enabledThumbRadius = 10.0,
     this.disabledThumbRadius,
   });
 
   /// The preferred radius of the round thumb shape when the slider is enabled.
   ///
-  /// If it is not provided, then the material default is used.
+  /// If it is not provided, then the material default of 10 is used.
   final double enabledThumbRadius;
 
   /// The preferred radius of the round thumb shape when the slider is disabled.
   ///
-  /// If no disabledRadius is provided, then it is is derived from the enabled
-  /// thumb radius and has the same ratio of enabled size to disabled size as
-  /// the Material spec. The default resolves to 4, which is 2 / 3 of the
-  /// default enabled thumb.
+  /// If no disabledRadius is provided, then it is equal to the
+  /// [enabledThumbRadius]
   final double disabledThumbRadius;
-  // TODO(clocksmith): This needs to be updated once the thumb size is updated to the Material spec.
-  double get _disabledThumbRadius =>  disabledThumbRadius ?? enabledThumbRadius * 2 / 3;
+  double get _disabledThumbRadius =>  disabledThumbRadius ?? enabledThumbRadius;
 
   @override
   Size getPreferredSize(bool isEnabled, bool isDiscrete) {
@@ -1163,15 +1274,24 @@
   void paint(
     PaintingContext context,
     Offset center, {
-    Animation<double> activationAnimation,
-    Animation<double> enableAnimation,
-    bool isDiscrete,
-    TextPainter labelPainter,
-    RenderBox parentBox,
-    SliderThemeData sliderTheme,
-    TextDirection textDirection,
-    double value,
+    @required Animation<double> activationAnimation,
+    @required Animation<double> enableAnimation,
+    bool isDiscrete = false,
+    @required TextPainter labelPainter,
+    @required RenderBox parentBox,
+    @required SliderThemeData sliderTheme,
+    @required TextDirection textDirection,
+    @required double value,
   }) {
+    assert(context != null);
+    assert(center != null);
+    assert(activationAnimation != null);
+    assert(enableAnimation != null);
+    assert(labelPainter != null);
+    assert(parentBox != null);
+    assert(sliderTheme != null);
+    assert(textDirection != null);
+    assert(value != null);
     final Canvas canvas = context.canvas;
     final Tween<double> radiusTween = Tween<double>(
       begin: _disabledThumbRadius,
@@ -1206,8 +1326,7 @@
 ///    sliders in a widget subtree.
 class RoundSliderOverlayShape extends SliderComponentShape {
   /// Create a slider thumb overlay that draws a circle.
-  // TODO(clocksmith): This needs to be changed to 24 according to spec.
-  const RoundSliderOverlayShape({ this.overlayRadius = 16.0 });
+  const RoundSliderOverlayShape({ this.overlayRadius = 24.0 });
 
   /// The preferred radius of the round thumb shape when enabled.
   ///
@@ -1223,26 +1342,30 @@
   void paint(
     PaintingContext context,
     Offset center, {
-    Animation<double> activationAnimation,
-    Animation<double> enableAnimation,
-    bool isDiscrete,
-    TextPainter labelPainter,
-    RenderBox parentBox,
-    SliderThemeData sliderTheme,
-    TextDirection textDirection,
-    double value,
+    @required Animation<double> activationAnimation,
+    @required Animation<double> enableAnimation,
+    bool isDiscrete = false,
+    @required TextPainter labelPainter,
+    @required RenderBox parentBox,
+    @required SliderThemeData sliderTheme,
+    @required TextDirection textDirection,
+    @required double value,
   }) {
+    assert(context != null);
+    assert(center != null);
+    assert(activationAnimation != null);
+    assert(enableAnimation != null);
+    assert(labelPainter != null);
+    assert(parentBox != null);
+    assert(sliderTheme != null);
+    assert(textDirection != null);
+    assert(value != null);
     final Canvas canvas = context.canvas;
     final Tween<double> radiusTween = Tween<double>(
       begin: 0.0,
       end: overlayRadius,
     );
 
-    // TODO(gspencer): We don't really follow the spec here for overlays.
-    // The spec says to use 16% opacity for drawing over light material,
-    // and 32% for colored material, but we don't really have a way to
-    // know what the underlying color is, so there's no easy way to
-    // implement this. Choosing the "light" version for now.
     canvas.drawCircle(
       center,
       radiusTween.evaluate(activationAnimation),
@@ -1324,7 +1447,7 @@
     final Path path = Path();
     final Offset bottomKnobStart = Offset(
       _bottomLobeRadius * math.cos(_bottomLobeStartAngle),
-      _bottomLobeRadius * math.sin(_bottomLobeStartAngle),
+      _bottomLobeRadius * math.sin(_bottomLobeStartAngle) - 2,
     );
     final Offset bottomNeckRightCenter = bottomKnobStart +
         Offset(
@@ -1474,7 +1597,7 @@
     // The distance between the end of the bottom neck arc and the beginning of
     // the top neck arc. We use this to shrink/expand it based on the scale
     // factor of the value indicator.
-    final double neckStretchBaseline = bottomLobeEnd.dy - math.max(neckLeftCenter.dy, neckRightCenter.dy);
+    final double neckStretchBaseline = math.max(0.0, bottomLobeEnd.dy - math.max(neckLeftCenter.dy, neckRightCenter.dy));
     final double t = math.pow(inverseTextScale, 3.0);
     final double stretch = (neckStretchBaseline * t).clamp(0.0, 10.0 * neckStretchBaseline);
     final Offset neckStretch = Offset(0.0, neckStretchBaseline - stretch);
@@ -1540,15 +1663,24 @@
   void paint(
     PaintingContext context,
     Offset center, {
-    Animation<double> activationAnimation,
-    Animation<double> enableAnimation,
-    bool isDiscrete,
-    TextPainter labelPainter,
-    RenderBox parentBox,
-    SliderThemeData sliderTheme,
-    TextDirection textDirection,
-    double value,
+    @required Animation<double> activationAnimation,
+    @required Animation<double> enableAnimation,
+    bool isDiscrete = false,
+    @required TextPainter labelPainter,
+    @required RenderBox parentBox,
+    @required SliderThemeData sliderTheme,
+    @required TextDirection textDirection,
+    @required double value,
   }) {
+    assert(context != null);
+    assert(center != null);
+    assert(activationAnimation != null);
+    assert(enableAnimation != null);
+    assert(labelPainter != null);
+    assert(parentBox != null);
+    assert(sliderTheme != null);
+    assert(textDirection != null);
+    assert(value != null);
     final ColorTween enableColor = ColorTween(
       begin: sliderTheme.disabledThumbColor,
       end: sliderTheme.valueIndicatorColor,
diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart
index d1db506..e124d31 100644
--- a/packages/flutter/lib/src/material/theme_data.dart
+++ b/packages/flutter/lib/src/material/theme_data.dart
@@ -243,12 +243,7 @@
     highlightColor ??= isDark ? _kDarkThemeHighlightColor : _kLightThemeHighlightColor;
     splashColor ??= isDark ? _kDarkThemeSplashColor : _kLightThemeSplashColor;
 
-    sliderTheme ??= SliderThemeData.fromPrimaryColors(
-      primaryColor: primaryColor,
-      primaryColorLight: primaryColorLight,
-      primaryColorDark: primaryColorDark,
-      valueIndicatorTextStyle: accentTextTheme.body2,
-    );
+    sliderTheme ??= const SliderThemeData();
     tabBarTheme ??= const TabBarTheme();
     appBarTheme ??= const AppBarTheme();
     bottomAppBarTheme ??= const BottomAppBarTheme();
diff --git a/packages/flutter/test/material/slider_test.dart b/packages/flutter/test/material/slider_test.dart
index e10459b..8f7c092 100644
--- a/packages/flutter/test/material/slider_test.dart
+++ b/packages/flutter/test/material/slider_test.dart
@@ -298,8 +298,8 @@
     );
 
     final List<Offset> expectedLog = <Offset>[
-      const Offset(16.0, 300.0),
-      const Offset(16.0, 300.0),
+      const Offset(24.0, 300.0),
+      const Offset(24.0, 300.0),
       const Offset(400.0, 300.0),
     ];
     final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(sliderKey)));
@@ -313,20 +313,20 @@
     await tester.pump(const Duration(milliseconds: 10));
     expect(value, equals(0.0));
     expect(log.length, 5);
-    expect(log.last.dx, closeTo(386.3, 0.1));
+    expect(log.last.dx, closeTo(386.6, 0.1));
     // With no more gesture or value changes, the thumb position should still
     // be redrawn in the animated position.
     await tester.pump();
     await tester.pump(const Duration(milliseconds: 10));
     expect(value, equals(0.0));
     expect(log.length, 7);
-    expect(log.last.dx, closeTo(343.3, 0.1));
+    expect(log.last.dx, closeTo(344.5, 0.1));
     // Final position.
     await tester.pump(const Duration(milliseconds: 80));
-    expectedLog.add(const Offset(16.0, 300.0));
+    expectedLog.add(const Offset(24.0, 300.0));
     expect(value, equals(0.0));
     expect(log.length, 8);
-    expect(log.last.dx, closeTo(16.0, 0.1));
+    expect(log.last.dx, closeTo(24.0, 0.1));
     await gesture.up();
   });
 
@@ -409,8 +409,8 @@
     );
 
     final List<Offset> expectedLog = <Offset>[
-      const Offset(16.0, 300.0),
-      const Offset(16.0, 300.0),
+      const Offset(24.0, 300.0),
+      const Offset(24.0, 300.0),
       const Offset(400.0, 300.0),
     ];
     final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(sliderKey)));
@@ -424,20 +424,20 @@
     await tester.pump(const Duration(milliseconds: 10));
     expect(value, equals(0.0));
     expect(log.length, 5);
-    expect(log.last.dx, closeTo(386.3, 0.1));
+    expect(log.last.dx, closeTo(386.6, 0.1));
     // With no more gesture or value changes, the thumb position should still
     // be redrawn in the animated position.
     await tester.pump();
     await tester.pump(const Duration(milliseconds: 10));
     expect(value, equals(0.0));
     expect(log.length, 7);
-    expect(log.last.dx, closeTo(343.3, 0.1));
+    expect(log.last.dx, closeTo(344.5, 0.1));
     // Final position.
     await tester.pump(const Duration(milliseconds: 80));
-    expectedLog.add(const Offset(16.0, 300.0));
+    expectedLog.add(const Offset(24.0, 300.0));
     expect(value, equals(0.0));
     expect(log.length, 8);
-    expect(log.last.dx, closeTo(16.0, 0.1));
+    expect(log.last.dx, closeTo(24.0, 0.1));
     await gesture.up();
   });
 
@@ -546,6 +546,20 @@
     final ThemeData theme = ThemeData(
       platform: TargetPlatform.android,
       primarySwatch: Colors.blue,
+      sliderTheme: const SliderThemeData(
+        disabledThumbColor: Color(0xff000001),
+        disabledActiveTickMarkColor: Color(0xff000002),
+        disabledActiveTrackColor: Color(0xff000003),
+        disabledInactiveTickMarkColor: Color(0xff000004),
+        disabledInactiveTrackColor: Color(0xff000005),
+        activeTrackColor: Color(0xff000006),
+        activeTickMarkColor: Color(0xff000007),
+        inactiveTrackColor: Color(0xff000008),
+        inactiveTickMarkColor: Color(0xff000009),
+        overlayColor: Color(0xff000010),
+        thumbColor: Color(0xff000011),
+        valueIndicatorColor: Color(0xff000012),
+      )
     );
     final SliderThemeData sliderTheme = theme.sliderTheme;
     double value = 0.45;
@@ -724,7 +738,7 @@
       paints
         ..rect(color: customColor1) // active track
         ..rect(color: customColor2) // inactive track
-        ..circle(color: customColor1.withAlpha(0x29)) // overlay
+        ..circle(color: customColor1.withOpacity(0.12)) // overlay
         ..circle(color: customColor2) // 1st tick mark
         ..circle(color: customColor2) // 2nd tick mark
         ..circle(color: customColor2) // 3rd tick mark
@@ -858,7 +872,7 @@
         ),
       ),
     ));
-    expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 16.0, 600.0));
+    expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 24.0, 600.0));
 
     await tester.pumpWidget(Directionality(
       textDirection: TextDirection.ltr,
@@ -878,7 +892,7 @@
         ),
       ),
     ));
-    expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 16.0, 32.0));
+    expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 24.0, 48.0));
   });
 
   testWidgets('Slider respects textScaleFactor', (WidgetTester tester) async {
@@ -1077,12 +1091,12 @@
       expect(
         sliderBox,
         paints
-          ..circle(x: 17.0, y: 16.0, radius: 1.0)
-          ..circle(x: 208.5, y: 16.0, radius: 1.0)
-          ..circle(x: 400.0, y: 16.0, radius: 1.0)
-          ..circle(x: 591.5, y: 16.0, radius: 1.0)
-          ..circle(x: 783.0, y: 16.0, radius: 1.0)
-          ..circle(x: 16.0, y: 16.0, radius: 6.0),
+          ..circle(x: 25.0, y: 24.0, radius: 1.0)
+          ..circle(x: 212.5, y: 24.0, radius: 1.0)
+          ..circle(x: 400.0, y: 24.0, radius: 1.0)
+          ..circle(x: 587.5, y: 24.0, radius: 1.0)
+          ..circle(x: 775.0, y: 24.0, radius: 1.0)
+          ..circle(x: 24.0, y: 24.0, radius: 10.0),
       );
 
       gesture = await tester.startGesture(center);
@@ -1093,13 +1107,13 @@
       expect(
         sliderBox,
         paints
-          ..circle(x: 105.0625, y: 16.0, radius: 3.791776657104492)
-          ..circle(x: 17.0, y: 16.0, radius: 1.0)
-          ..circle(x: 208.5, y: 16.0, radius: 1.0)
-          ..circle(x: 400.0, y: 16.0, radius: 1.0)
-          ..circle(x: 591.5, y: 16.0, radius: 1.0)
-          ..circle(x: 783.0, y: 16.0, radius: 1.0)
-          ..circle(x: 105.0625, y: 16.0, radius: 6.0),
+          ..circle(x: 111.20703125, y: 24.0, radius: 5.687664985656738)
+          ..circle(x: 25.0, y: 24.0, radius: 1.0)
+          ..circle(x: 212.5, y: 24.0, radius: 1.0)
+          ..circle(x: 400.0, y: 24.0, radius: 1.0)
+          ..circle(x: 587.5, y: 24.0, radius: 1.0)
+          ..circle(x: 775.0, y: 24.0, radius: 1.0)
+          ..circle(x: 111.20703125, y: 24.0, radius: 10.0),
       );
 
       // Reparenting in the middle of an animation should do nothing.
@@ -1113,13 +1127,13 @@
       expect(
         sliderBox,
         paints
-          ..circle(x: 185.5457763671875, y: 16.0, radius: 8.0)
-          ..circle(x: 17.0, y: 16.0, radius: 1.0)
-          ..circle(x: 208.5, y: 16.0, radius: 1.0)
-          ..circle(x: 400.0, y: 16.0, radius: 1.0)
-          ..circle(x: 591.5, y: 16.0, radius: 1.0)
-          ..circle(x: 783.0, y: 16.0, radius: 1.0)
-          ..circle(x: 185.5457763671875, y: 16.0, radius: 6.0),
+          ..circle(x: 190.0135726928711, y: 24.0, radius: 12.0)
+          ..circle(x: 25.0, y: 24.0, radius: 1.0)
+          ..circle(x: 212.5, y: 24.0, radius: 1.0)
+          ..circle(x: 400.0, y: 24.0, radius: 1.0)
+          ..circle(x: 587.5, y: 24.0, radius: 1.0)
+          ..circle(x: 775.0, y: 24.0, radius: 1.0)
+          ..circle(x: 190.0135726928711, y: 24.0, radius: 10.0),
       );
       // Wait for animations to finish.
       await tester.pumpAndSettle();
@@ -1127,13 +1141,13 @@
       expect(
         sliderBox,
         paints
-          ..circle(x: 400.0, y: 16.0, radius: 16.0)
-          ..circle(x: 17.0, y: 16.0, radius: 1.0)
-          ..circle(x: 208.5, y: 16.0, radius: 1.0)
-          ..circle(x: 400.0, y: 16.0, radius: 1.0)
-          ..circle(x: 591.5, y: 16.0, radius: 1.0)
-          ..circle(x: 783.0, y: 16.0, radius: 1.0)
-          ..circle(x: 400.0, y: 16.0, radius: 6.0),
+          ..circle(x: 400.0, y: 24.0, radius: 24.0)
+          ..circle(x: 25.0, y: 24.0, radius: 1.0)
+          ..circle(x: 212.5, y: 24.0, radius: 1.0)
+          ..circle(x: 400.0, y: 24.0, radius: 1.0)
+          ..circle(x: 587.5, y: 24.0, radius: 1.0)
+          ..circle(x: 775.0, y: 24.0, radius: 1.0)
+          ..circle(x: 400.0, y: 24.0, radius: 10.0),
       );
       await gesture.up();
       await tester.pumpAndSettle();
@@ -1141,12 +1155,12 @@
       expect(
         sliderBox,
         paints
-          ..circle(x: 17.0, y: 16.0, radius: 1.0)
-          ..circle(x: 208.5, y: 16.0, radius: 1.0)
-          ..circle(x: 400.0, y: 16.0, radius: 1.0)
-          ..circle(x: 591.5, y: 16.0, radius: 1.0)
-          ..circle(x: 783.0, y: 16.0, radius: 1.0)
-          ..circle(x: 400.0, y: 16.0, radius: 6.0),
+          ..circle(x: 25.0, y: 24.0, radius: 1.0)
+          ..circle(x: 212.5, y: 24.0, radius: 1.0)
+          ..circle(x: 400.0, y: 24.0, radius: 1.0)
+          ..circle(x: 587.5, y: 24.0, radius: 1.0)
+          ..circle(x: 775.0, y: 24.0, radius: 1.0)
+          ..circle(x: 400.0, y: 24.0, radius: 10.0),
       );
     }
 
diff --git a/packages/flutter/test/material/slider_theme_test.dart b/packages/flutter/test/material/slider_theme_test.dart
index a3ff5e8..58e2178 100644
--- a/packages/flutter/test/material/slider_theme_test.dart
+++ b/packages/flutter/test/material/slider_theme_test.dart
@@ -12,17 +12,6 @@
 import '../rendering/mock_canvas.dart';
 
 void main() {
-  testWidgets('Slider theme is built by ThemeData', (WidgetTester tester) async {
-    final ThemeData theme = ThemeData(
-      platform: TargetPlatform.android,
-      primarySwatch: Colors.red,
-    );
-    final SliderThemeData sliderTheme = theme.sliderTheme;
-
-    expect(sliderTheme.activeTrackColor.value, equals(Colors.red.value));
-    expect(sliderTheme.inactiveTrackColor.value, equals(Colors.red.withAlpha(0x3d).value));
-  });
-
   testWidgets('Slider uses ThemeData slider theme if present', (WidgetTester tester) async {
     final ThemeData theme = ThemeData(
       platform: TargetPlatform.android,
@@ -63,20 +52,6 @@
     );
   });
 
-  testWidgets('SliderThemeData assigns the correct default shapes', (WidgetTester tester) async {
-    final SliderThemeData sliderTheme = ThemeData().sliderTheme;
-    expect(sliderTheme.trackShape, equals(isInstanceOf<RectangularSliderTrackShape>()));
-    expect(sliderTheme.tickMarkShape, equals(isInstanceOf<RoundSliderTickMarkShape>()));
-    expect(sliderTheme.thumbShape, equals(isInstanceOf<RoundSliderThumbShape>()));
-    expect(sliderTheme.valueIndicatorShape, equals(isInstanceOf<PaddleSliderValueIndicatorShape>()));
-    expect(sliderTheme.overlayShape, equals(isInstanceOf<RoundSliderOverlayShape>()));
-  });
-
-  testWidgets('SliderThemeData assigns the correct default flags', (WidgetTester tester) async {
-    final SliderThemeData sliderTheme = ThemeData().sliderTheme;
-    expect(sliderTheme.showValueIndicator, equals(ShowValueIndicator.onlyForDiscrete));
-  });
-
   testWidgets('SliderThemeData generates correct opacities for fromPrimaryColors', (WidgetTester tester) async {
     const Color customColor1 = Color(0xcafefeed);
     const Color customColor2 = Color(0xdeadbeef);
@@ -100,7 +75,7 @@
     expect(sliderTheme.disabledInactiveTickMarkColor, equals(customColor2.withAlpha(0x1f)));
     expect(sliderTheme.thumbColor, equals(customColor1.withAlpha(0xff)));
     expect(sliderTheme.disabledThumbColor, equals(customColor2.withAlpha(0x52)));
-    expect(sliderTheme.overlayColor, equals(customColor1.withAlpha(0x29)));
+    expect(sliderTheme.overlayColor, equals(customColor1.withAlpha(0x1f)));
     expect(sliderTheme.valueIndicatorColor, equals(customColor1.withAlpha(0xff)));
     expect(sliderTheme.valueIndicatorTextStyle.color, equals(customColor4));
   });
@@ -132,7 +107,7 @@
     expect(lerp.disabledInactiveTickMarkColor, equals(middleGrey.withAlpha(0x1f)));
     expect(lerp.thumbColor, equals(middleGrey.withAlpha(0xff)));
     expect(lerp.disabledThumbColor, equals(middleGrey.withAlpha(0x52)));
-    expect(lerp.overlayColor, equals(middleGrey.withAlpha(0x29)));
+    expect(lerp.overlayColor, equals(middleGrey.withAlpha(0x1f)));
     expect(lerp.valueIndicatorColor, equals(middleGrey.withAlpha(0xff)));
     expect(lerp.valueIndicatorTextStyle.color, equals(middleGrey.withAlpha(0xff)));
   });
@@ -152,8 +127,8 @@
     expect(
       sliderBox,
       paints
-        ..rect(rect: Rect.fromLTRB(16.0, 299.0, 208.0, 301.0), color: sliderTheme.activeTrackColor)
-        ..rect(rect: Rect.fromLTRB(208.0, 299.0, 784.0, 301.0), color: sliderTheme.inactiveTrackColor),
+        ..rect(rect: Rect.fromLTRB(25.0, 299.0, 202.0, 301.0), color: sliderTheme.activeTrackColor)
+        ..rect(rect: Rect.fromLTRB(222.0, 299.0, 776.0, 301.0), color: sliderTheme.inactiveTrackColor),
     );
 
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false));
@@ -168,8 +143,8 @@
     expect(
       sliderBox,
       paints
-        ..rect(rect: Rect.fromLTRB(16.0, 299.0, 202.0, 301.0), color: sliderTheme.disabledActiveTrackColor)
-        ..rect(rect: Rect.fromLTRB(214.0, 299.0, 784.0, 301.0), color: sliderTheme.disabledInactiveTrackColor),
+        ..rect(rect: Rect.fromLTRB(25.0, 299.0, 202.0, 301.0), color: sliderTheme.disabledActiveTrackColor)
+        ..rect(rect: Rect.fromLTRB(222.0, 299.0, 776.0, 301.0), color: sliderTheme.disabledInactiveTrackColor),
     );
   });
 
@@ -189,9 +164,9 @@
       paints
         ..circle(
           color: sliderTheme.thumbColor,
-          x: 208.0,
+          x: 212.0,
           y: 300.0,
-          radius: 6.0,
+          radius: 10.0,
         ),
     );
 
@@ -206,15 +181,15 @@
       paints
         ..circle(
           color: sliderTheme.overlayColor,
-          x: 208.0,
+          x: 212.0,
           y: 300.0,
-          radius: 16.0,
+          radius: 24.0,
         )
         ..circle(
           color: sliderTheme.thumbColor,
-          x: 208.0,
+          x: 212.0,
           y: 300.0,
-          radius: 6.0,
+          radius: 10.0,
         ),
     );
 
@@ -227,9 +202,9 @@
       paints
         ..circle(
           color: sliderTheme.thumbColor,
-          x: 208.0,
+          x: 212.0,
           y: 300.0,
-          radius: 6.0,
+          radius: 10.0,
         ),
     );
   });
@@ -244,12 +219,12 @@
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.45));
     final RenderBox sliderBox = tester.firstRenderObject<RenderBox>(find.byType(Slider));
 
-    expect(sliderBox, paints..circle(color: sliderTheme.thumbColor, radius: 6.0));
+    expect(sliderBox, paints..circle(color: sliderTheme.thumbColor, radius: 10.0));
 
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.45, enabled: false));
     await tester.pumpAndSettle(); // wait for disable animation
 
-    expect(sliderBox, paints..circle(color: sliderTheme.disabledThumbColor, radius: 4.0));
+    expect(sliderBox, paints..circle(color: sliderTheme.disabledThumbColor, radius: 10.0));
 
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.45, divisions: 3));
     await tester.pumpAndSettle(); // wait for enable animation
@@ -261,7 +236,7 @@
         ..circle(color: sliderTheme.activeTickMarkColor)
         ..circle(color: sliderTheme.inactiveTickMarkColor)
         ..circle(color: sliderTheme.inactiveTickMarkColor)
-        ..circle(color: sliderTheme.thumbColor, radius: 6.0),
+        ..circle(color: sliderTheme.thumbColor, radius: 10.0),
     );
 
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.45, divisions: 3, enabled: false));
@@ -274,7 +249,7 @@
         ..circle(color: sliderTheme.disabledInactiveTickMarkColor)
         ..circle(color: sliderTheme.disabledInactiveTickMarkColor)
         ..circle(color: sliderTheme.disabledInactiveTickMarkColor)
-        ..circle(color: sliderTheme.disabledThumbColor, radius: 4.0),
+        ..circle(color: sliderTheme.disabledThumbColor, radius: 10.0),
     );
   });
 
@@ -368,10 +343,10 @@
           color: sliderTheme.valueIndicatorColor,
           includes: <Offset>[
             const Offset(0.0, -40.0),
-            const Offset(98.0, -40.0),
+            const Offset(92.0, -40.0),
             const Offset(-16.0, -40.0),
           ],
-          excludes: <Offset>[const Offset(98.1, -40.0), const Offset(-16.1, -40.0)],
+          excludes: <Offset>[const Offset(98.1, -40.0), const Offset(-20.1, -40.0)],
         ),
     );
     await gesture.up();
@@ -390,9 +365,9 @@
           includes: <Offset>[
             const Offset(0.0, -40.0),
             const Offset(16.0, -40.0),
-            const Offset(-98.0, -40.0),
+            const Offset(-92.0, -40.0),
           ],
-          excludes: <Offset>[const Offset(16.1, -40.0), const Offset(-98.1, -40.0)],
+          excludes: <Offset>[const Offset(20.1, -40.0), const Offset(-98.1, -40.0)],
         ),
     );
     await gesture.up();
@@ -410,14 +385,14 @@
           color: sliderTheme.valueIndicatorColor,
           includes: <Offset>[
             const Offset(0.0, -49.0),
-            const Offset(90.0, -49.0),
+            const Offset(68.0, -49.0),
             const Offset(-24.0, -49.0),
           ],
           excludes: <Offset>[
             const Offset(98.0, -32.0),  // inside full size, outside small
-            const Offset(-16.0, -32.0),  // inside full size, outside small
+            const Offset(-40.0, -32.0),  // inside full size, outside small
             const Offset(90.1, -49.0),
-            const Offset(-24.1, -49.0),
+            const Offset(-40.1, -49.0),
           ],
         ),
     );
@@ -436,10 +411,9 @@
           color: sliderTheme.valueIndicatorColor,
           includes: <Offset>[
             const Offset(0.0, -38.8),
-            const Offset(98.0, -38.8),
-            const Offset(-16.0, -38.8),
-            const Offset(10.0, -23.0), // Inside large, outside scale=1.0
-            const Offset(-4.0, -23.0), // Inside large, outside scale=1.0
+            const Offset(92.0, -38.8),
+            const Offset(8.0, -23.0), // Inside large, outside scale=1.0
+            const Offset(-2.0, -23.0), // Inside large, outside scale=1.0
           ],
           excludes: <Offset>[
             const Offset(98.5, -38.8),
@@ -461,8 +435,8 @@
     expect(
       sliderBox,
       paints
-        ..rect(rect: Rect.fromLTRB(16.0, 292.0, 208.0, 308.0), color: sliderTheme.activeTrackColor)
-        ..rect(rect: Rect.fromLTRB(208.0, 292.0, 784.0, 308.0), color: sliderTheme.inactiveTrackColor),
+        ..rect(rect: Rect.fromLTRB(32.0, 292.0, 202.0, 308.0), color: sliderTheme.activeTrackColor)
+        ..rect(rect: Rect.fromLTRB(222.0, 292.0, 776.0, 308.0), color: sliderTheme.inactiveTrackColor),
     );
 
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false));
@@ -473,8 +447,8 @@
     expect(
       sliderBox,
       paints
-        ..rect(rect: Rect.fromLTRB(16.0, 292.0, 202.0, 308.0), color: sliderTheme.disabledActiveTrackColor)
-        ..rect(rect: Rect.fromLTRB(214.0, 292.0, 784.0, 308.0), color: sliderTheme.disabledInactiveTrackColor),
+        ..rect(rect: Rect.fromLTRB(32.0, 292.0, 202.0, 308.0), color: sliderTheme.disabledActiveTrackColor)
+        ..rect(rect: Rect.fromLTRB(222.0, 292.0, 776.0, 308.0), color: sliderTheme.disabledInactiveTrackColor),
     );
   });
 
@@ -491,7 +465,7 @@
 
     expect(
       sliderBox,
-      paints..circle(x: 208, y: 300, radius: 7, color: sliderTheme.thumbColor),
+      paints..circle(x: 212, y: 300, radius: 7, color: sliderTheme.thumbColor),
     );
 
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false));
@@ -499,7 +473,7 @@
 
     expect(
       sliderBox,
-      paints..circle(x: 208, y: 300, radius: 11, color: sliderTheme.disabledThumbColor),
+      paints..circle(x: 212, y: 300, radius: 11, color: sliderTheme.disabledThumbColor),
     );
   });
 
@@ -515,26 +489,21 @@
 
     expect(
       sliderBox,
-      paints..circle(x: 208, y: 300, radius: 9, color: sliderTheme.thumbColor),
+      paints..circle(x: 212, y: 300, radius: 9, color: sliderTheme.thumbColor),
     );
 
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false));
     await tester.pumpAndSettle(); // wait for disable animation
-    // Radius should be 6, or 2/3 of 9. 2/3 because the default disabled thumb
-    // radius is 4 and the default enabled thumb radius is 6.
-    // TODO(clocksmith): This ratio will change once thumb sizes are updated to spec.
     expect(
       sliderBox,
-      paints..circle(x: 208, y: 300, radius: 6, color: sliderTheme.disabledThumbColor),
+      paints..circle(x: 212, y: 300, radius: 9, color: sliderTheme.disabledThumbColor),
     );
   });
 
 
   testWidgets('The default slider tick mark shape size can be overridden', (WidgetTester tester) async {
     final SliderThemeData sliderTheme = ThemeData().sliderTheme.copyWith(
-      tickMarkShape: const RoundSliderTickMarkShape(
-        tickMarkRadius: 5
-      ),
+      tickMarkShape: const RoundSliderTickMarkShape(tickMarkRadius: 5),
       activeTickMarkColor: const Color(0xfadedead),
       inactiveTickMarkColor: const Color(0xfadebeef),
       disabledActiveTickMarkColor: const Color(0xfadecafe),
@@ -548,9 +517,9 @@
     expect(
       sliderBox,
       paints
-        ..circle(x: 21, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor)
+        ..circle(x: 29, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor)
         ..circle(x: 400, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor)
-        ..circle(x: 779, y: 300, radius: 5, color: sliderTheme.inactiveTickMarkColor),
+        ..circle(x: 771, y: 300, radius: 5, color: sliderTheme.inactiveTickMarkColor),
     );
 
     await tester.pumpWidget(_buildApp(sliderTheme, value: 0.5, divisions: 2,  enabled: false));
@@ -559,9 +528,9 @@
     expect(
       sliderBox,
       paints
-        ..circle(x: 21, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor)
+        ..circle(x: 29, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor)
         ..circle(x: 400, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor)
-        ..circle(x: 779, y: 300, radius: 5, color: sliderTheme.disabledInactiveTickMarkColor),
+        ..circle(x: 771, y: 300, radius: 5, color: sliderTheme.disabledInactiveTickMarkColor),
     );
   });
 
diff --git a/packages/flutter/test/material/theme_data_test.dart b/packages/flutter/test/material/theme_data_test.dart
index c56c6e1..d191ff4 100644
--- a/packages/flutter/test/material/theme_data_test.dart
+++ b/packages/flutter/test/material/theme_data_test.dart
@@ -56,16 +56,6 @@
     expect(darkTheme.accentTextTheme.title.color, typography.white.title.color);
   });
 
-  test('Default slider indicator style gets a default body2 if accentTextTheme.body2 is null', () {
-    const TextTheme noBody2TextTheme = TextTheme(body2: null);
-    final ThemeData lightTheme = ThemeData(brightness: Brightness.light, accentTextTheme: noBody2TextTheme);
-    final ThemeData darkTheme = ThemeData(brightness: Brightness.dark, accentTextTheme: noBody2TextTheme);
-    final Typography typography = Typography(platform: lightTheme.platform);
-
-    expect(lightTheme.sliderTheme.valueIndicatorTextStyle, equals(typography.white.body2));
-    expect(darkTheme.sliderTheme.valueIndicatorTextStyle, equals(typography.black.body2));
-  });
-
   test('Default chip label style gets a default body2 if textTheme.body2 is null', () {
     const TextTheme noBody2TextTheme = TextTheme(body2: null);
     final ThemeData lightTheme = ThemeData(brightness: Brightness.light, textTheme: noBody2TextTheme);