Add a platform field to Theme (#5024)
We'll use this field to adapt material widgets to iOS.
This commit is contained in:
parent
486b783076
commit
5717cd54e0
@ -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';
|
||||
|
12
packages/flutter/lib/src/foundation/platform.dart
Normal file
12
packages/flutter/lib/src/foundation/platform.dart
Normal file
@ -0,0 +1,12 @@
|
||||
// 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
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user