Commit 5717cd54 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add a platform field to Theme (#5024)

We'll use this field to adapt material widgets to iOS.
parent 486b7830
......@@ -14,5 +14,6 @@ export 'src/foundation/basic_types.dart';
export 'src/foundation/binding.dart';
export 'src/foundation/change_notifier.dart';
export 'src/foundation/licenses.dart';
export 'src/foundation/platform.dart';
export 'src/foundation/print.dart';
export 'src/foundation/synchronous_future.dart';
// Copyright 2016 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.
/// The platform that user interaction should adapt to target.
enum TargetPlatform {
/// Android: <https://www.android.com/>
android,
/// iOS: <http://www.apple.com/ios/>
iOS,
}
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io' show Platform;
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
......@@ -25,6 +23,15 @@ const TextStyle _errorTextStyle = const TextStyle(
decorationStyle: TextDecorationStyle.double
);
/// The visual and interaction design for overscroll.
enum OverscrollStyle {
/// Overscrolls are clamped and indicated with a glow.
glow,
/// Overscrolls are not clamped and indicated with elastic physics.
bounce
}
/// An application that uses material design.
///
/// A convenience widget that wraps a number of widgets that are commonly
......@@ -53,6 +60,7 @@ class MaterialApp extends StatefulWidget {
this.theme,
this.home,
this.routes: const <String, WidgetBuilder>{},
this.overscrollStyle,
this.onGenerateRoute,
this.onLocaleChanged,
this.debugShowMaterialGrid: false,
......@@ -104,6 +112,11 @@ class MaterialApp extends StatefulWidget {
/// build the page instead.
final Map<String, WidgetBuilder> routes;
/// The visual and interaction design for overscroll.
///
/// Defaults to being adapted to the current [TargetPlatform].
final OverscrollStyle overscrollStyle;
/// The route generator callback used when the app is navigated to a
/// named route.
final RouteFactory onGenerateRoute;
......@@ -149,7 +162,8 @@ class _IndicatorScrollConfigurationDelegate extends ScrollConfigurationDelegate
@override
Widget wrapScrollWidget(Widget scrollWidget) => new OverscrollIndicator(child: scrollWidget);
}
final ScrollConfigurationDelegate _indicatorScroll = new _IndicatorScrollConfigurationDelegate();
final ScrollConfigurationDelegate _glowScroll = new _IndicatorScrollConfigurationDelegate();
final ScrollConfigurationDelegate _bounceScroll = new ScrollConfigurationDelegate();
class _MaterialAppState extends State<MaterialApp> {
......@@ -180,6 +194,24 @@ class _MaterialAppState extends State<MaterialApp> {
return null;
}
ScrollConfigurationDelegate _getScrollDelegate(TargetPlatform platform) {
if (config.overscrollStyle != null) {
switch (config.overscrollStyle) {
case OverscrollStyle.glow:
return _glowScroll;
case OverscrollStyle.bounce:
return _bounceScroll;
}
}
switch (platform) {
case TargetPlatform.android:
return _glowScroll;
case TargetPlatform.iOS:
return _bounceScroll;
}
return null;
}
@override
Widget build(BuildContext context) {
ThemeData theme = config.theme ?? new ThemeData.fallback();
......@@ -213,7 +245,7 @@ class _MaterialAppState extends State<MaterialApp> {
});
return new ScrollConfiguration(
delegate: (Platform.isIOS || Platform.isMacOS) ? _bounceScroll : _indicatorScroll,
delegate: _getScrollDelegate(theme.platform),
child: result
);
}
......
......@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io' show Platform;
import 'dart:ui' show Color, hashValues;
import 'package:flutter/foundation.dart';
import 'colors.dart';
import 'icon_theme_data.dart';
import 'typography.dart';
......@@ -90,7 +93,8 @@ class ThemeData {
TextTheme textTheme,
TextTheme primaryTextTheme,
IconThemeData iconTheme,
IconThemeData primaryIconTheme
IconThemeData primaryIconTheme,
TargetPlatform platform
}) {
brightness ??= Brightness.light;
final bool isDark = brightness == Brightness.dark;
......@@ -121,6 +125,7 @@ class ThemeData {
primaryTextTheme ??= primaryIsDark ? Typography.white : Typography.black;
iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
platform ??= (Platform.isIOS || Platform.isMacOS) ? TargetPlatform.iOS : TargetPlatform.android;
return new ThemeData.raw(
brightness: brightness,
primaryColor: primaryColor,
......@@ -146,7 +151,8 @@ class ThemeData {
textTheme: textTheme,
primaryTextTheme: primaryTextTheme,
iconTheme: iconTheme,
primaryIconTheme: primaryIconTheme
primaryIconTheme: primaryIconTheme,
platform: platform
);
}
......@@ -181,7 +187,8 @@ class ThemeData {
this.textTheme,
this.primaryTextTheme,
this.iconTheme,
this.primaryIconTheme
this.primaryIconTheme,
this.platform
}) {
assert(brightness != null);
assert(primaryColor != null);
......@@ -208,6 +215,7 @@ class ThemeData {
assert(primaryTextTheme != null);
assert(iconTheme != null);
assert(primaryIconTheme != null);
assert(platform != null);
}
/// A default light blue theme.
......@@ -320,6 +328,11 @@ class ThemeData {
/// An icon theme that contrasts with the primary color.
final IconThemeData primaryIconTheme;
/// The platform the material widgets should adapt to target.
///
/// Defaults to the current platform.
final TargetPlatform platform;
/// Linearly interpolate between two themes.
static ThemeData lerp(ThemeData begin, ThemeData end, double t) {
return new ThemeData.raw(
......@@ -347,7 +360,8 @@ class ThemeData {
textTheme: TextTheme.lerp(begin.textTheme, end.textTheme, t),
primaryTextTheme: TextTheme.lerp(begin.primaryTextTheme, end.primaryTextTheme, t),
iconTheme: IconThemeData.lerp(begin.iconTheme, end.iconTheme, t),
primaryIconTheme: IconThemeData.lerp(begin.primaryIconTheme, end.primaryIconTheme, t)
primaryIconTheme: IconThemeData.lerp(begin.primaryIconTheme, end.primaryIconTheme, t),
platform: t < 0.5 ? begin.platform : end.platform
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment