Support per-platform default typography (#6634)
On Android and Fuchsia, default to Roboto. On iOS, use San Francisco.
This commit is contained in:
parent
32c9b4cd80
commit
abcfc42dfc
@ -122,11 +122,13 @@ class ThemeData {
|
|||||||
indicatorColor ??= accentColor == primaryColor ? Colors.white : accentColor;
|
indicatorColor ??= accentColor == primaryColor ? Colors.white : accentColor;
|
||||||
hintColor ??= isDark ? const Color(0x42FFFFFF) : const Color(0x4C000000);
|
hintColor ??= isDark ? const Color(0x42FFFFFF) : const Color(0x4C000000);
|
||||||
errorColor ??= Colors.red[700];
|
errorColor ??= Colors.red[700];
|
||||||
textTheme ??= isDark ? Typography.white : Typography.black;
|
|
||||||
primaryTextTheme ??= primaryIsDark ? Typography.white : Typography.black;
|
|
||||||
iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.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);
|
primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
|
||||||
platform ??= defaultTargetPlatform;
|
platform ??= defaultTargetPlatform;
|
||||||
|
|
||||||
|
final Typography typography = new Typography(platform: platform);
|
||||||
|
primaryTextTheme ??= primaryIsDark ? typography.white : typography.black;
|
||||||
|
textTheme ??= isDark ? typography.white : typography.black;
|
||||||
return new ThemeData.raw(
|
return new ThemeData.raw(
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
primaryColor: primaryColor,
|
primaryColor: primaryColor,
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
import 'colors.dart';
|
import 'colors.dart';
|
||||||
|
|
||||||
@ -51,7 +53,7 @@ class TextTheme {
|
|||||||
this.button
|
this.button
|
||||||
});
|
});
|
||||||
|
|
||||||
const TextTheme._black()
|
const TextTheme._blackMountainView()
|
||||||
: display4 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 112.0, fontWeight: FontWeight.w100, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
: display4 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 112.0, fontWeight: FontWeight.w100, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
display3 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 56.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
display3 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 56.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
display2 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
display2 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
@ -64,7 +66,7 @@ class TextTheme {
|
|||||||
caption = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
caption = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
button = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.black87, textBaseline: TextBaseline.alphabetic);
|
button = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.black87, textBaseline: TextBaseline.alphabetic);
|
||||||
|
|
||||||
const TextTheme._white()
|
const TextTheme._whiteMountainView()
|
||||||
: display4 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 112.0, fontWeight: FontWeight.w100, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
: display4 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 112.0, fontWeight: FontWeight.w100, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
display3 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 56.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
display3 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 56.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
display2 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
display2 = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
@ -77,6 +79,32 @@ class TextTheme {
|
|||||||
caption = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
caption = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
button = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.white, textBaseline: TextBaseline.alphabetic);
|
button = const TextStyle(fontFamily: 'Roboto', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.white, textBaseline: TextBaseline.alphabetic);
|
||||||
|
|
||||||
|
const TextTheme._blackCupertino()
|
||||||
|
: display4 = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 112.0, fontWeight: FontWeight.w100, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
|
display3 = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 56.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
|
display2 = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
|
display1 = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 34.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
|
headline = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 24.0, fontWeight: FontWeight.w400, color: Colors.black87, textBaseline: TextBaseline.alphabetic),
|
||||||
|
title = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 20.0, fontWeight: FontWeight.w500, color: Colors.black87, textBaseline: TextBaseline.alphabetic),
|
||||||
|
subhead = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 16.0, fontWeight: FontWeight.w400, color: Colors.black87, textBaseline: TextBaseline.alphabetic),
|
||||||
|
body2 = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.black87, textBaseline: TextBaseline.alphabetic),
|
||||||
|
body1 = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w400, color: Colors.black87, textBaseline: TextBaseline.alphabetic),
|
||||||
|
caption = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, color: Colors.black54, textBaseline: TextBaseline.alphabetic),
|
||||||
|
button = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.black87, textBaseline: TextBaseline.alphabetic);
|
||||||
|
|
||||||
|
const TextTheme._whiteCupertino()
|
||||||
|
: display4 = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 112.0, fontWeight: FontWeight.w100, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
|
display3 = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 56.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
|
display2 = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
|
display1 = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 34.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
|
headline = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 24.0, fontWeight: FontWeight.w400, color: Colors.white, textBaseline: TextBaseline.alphabetic),
|
||||||
|
title = const TextStyle(fontFamily: '.SF UI Display', inherit: false, fontSize: 20.0, fontWeight: FontWeight.w500, color: Colors.white, textBaseline: TextBaseline.alphabetic),
|
||||||
|
subhead = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 16.0, fontWeight: FontWeight.w400, color: Colors.white, textBaseline: TextBaseline.alphabetic),
|
||||||
|
body2 = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.white, textBaseline: TextBaseline.alphabetic),
|
||||||
|
body1 = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w400, color: Colors.white, textBaseline: TextBaseline.alphabetic),
|
||||||
|
caption = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, color: Colors.white70, textBaseline: TextBaseline.alphabetic),
|
||||||
|
button = const TextStyle(fontFamily: '.SF UI Text', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, color: Colors.white, textBaseline: TextBaseline.alphabetic);
|
||||||
|
|
||||||
/// Extremely large text.
|
/// Extremely large text.
|
||||||
///
|
///
|
||||||
/// The font size is 112 pixels.
|
/// The font size is 112 pixels.
|
||||||
@ -255,10 +283,10 @@ class TextTheme {
|
|||||||
|
|
||||||
/// The two material design text themes.
|
/// The two material design text themes.
|
||||||
///
|
///
|
||||||
/// [Typography.black] and [Typography.white] define the two text themes used in
|
/// Material design defines two text themes: [black] and [white]. The black
|
||||||
/// material design. The black text theme, which uses dark glyphs, is used on
|
/// text theme, which uses dark glyphs, is used on light backgrounds in light
|
||||||
/// light backgrounds in light themes. The white text theme, which uses light
|
/// themes. The white text theme, which uses light glyphs, is used in dark
|
||||||
/// glyphs, is used in dark themes and on dark backgrounds in in light themes.
|
/// themes and on dark backgrounds in light themes.
|
||||||
///
|
///
|
||||||
/// To obtain the current text theme, call [Theme.of] with the current
|
/// To obtain the current text theme, call [Theme.of] with the current
|
||||||
/// [BuildContext] and read the [ThemeData.textTheme] property.
|
/// [BuildContext] and read the [ThemeData.textTheme] property.
|
||||||
@ -269,11 +297,30 @@ class TextTheme {
|
|||||||
/// * [ThemeData]
|
/// * [ThemeData]
|
||||||
/// * <http://material.google.com/style/typography.html>
|
/// * <http://material.google.com/style/typography.html>
|
||||||
class Typography {
|
class Typography {
|
||||||
Typography._();
|
/// Creates the default typography for the specified platform.
|
||||||
|
factory Typography({ @required TargetPlatform platform }) {
|
||||||
|
assert(platform != null);
|
||||||
|
switch (platform) {
|
||||||
|
case TargetPlatform.android:
|
||||||
|
case TargetPlatform.fuchsia:
|
||||||
|
return const Typography._(
|
||||||
|
const TextTheme._blackMountainView(),
|
||||||
|
const TextTheme._whiteMountainView(),
|
||||||
|
);
|
||||||
|
case TargetPlatform.iOS:
|
||||||
|
return const Typography._(
|
||||||
|
const TextTheme._blackCupertino(),
|
||||||
|
const TextTheme._whiteCupertino(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Typography._(this.black, this.white);
|
||||||
|
|
||||||
/// A material design text theme with dark glyphs.
|
/// A material design text theme with dark glyphs.
|
||||||
static const TextTheme black = const TextTheme._black();
|
final TextTheme black;
|
||||||
|
|
||||||
/// A material design text theme with light glyphs.
|
/// A material design text theme with light glyphs.
|
||||||
static const TextTheme white = const TextTheme._white();
|
final TextTheme white;
|
||||||
}
|
}
|
||||||
|
16
packages/flutter/test/material/theme_data_test.dart
Normal file
16
packages/flutter/test/material/theme_data_test.dart
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('Defaults to the default typography for the platform', () {
|
||||||
|
for (TargetPlatform platform in TargetPlatform.values) {
|
||||||
|
ThemeData theme = new ThemeData(platform: platform);
|
||||||
|
Typography typography = new Typography(platform: platform);
|
||||||
|
expect(theme.textTheme, typography.black, reason: 'Not using default typography for $platform');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
44
packages/flutter/test/material/typography_test.dart
Normal file
44
packages/flutter/test/material/typography_test.dart
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('Typography is defined for all target platforms', () {
|
||||||
|
for (TargetPlatform platform in TargetPlatform.values) {
|
||||||
|
Typography typography = new Typography(platform: platform);
|
||||||
|
expect(typography, isNotNull, reason: 'null typography for $platform');
|
||||||
|
expect(typography.black, isNotNull, reason: 'null black typography for $platform');
|
||||||
|
expect(typography.white, isNotNull, reason: 'null white typography for $platform');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Typography on Android, Fuchsia defaults to Roboto', () {
|
||||||
|
expect(new Typography(platform: TargetPlatform.android).black.title.fontFamily, 'Roboto');
|
||||||
|
expect(new Typography(platform: TargetPlatform.fuchsia).black.title.fontFamily, 'Roboto');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Typography on iOS defaults to the correct SF font family based on size', () {
|
||||||
|
// Ref: https://developer.apple.com/ios/human-interface-guidelines/visual-design/typography/
|
||||||
|
Matcher hasCorrectFont = predicate((TextStyle s) {
|
||||||
|
return s.fontFamily == (s.fontSize <= 19.0 ? '.SF UI Text' : '.SF UI Display');
|
||||||
|
}, 'Uses SF Display font for font sizes over 19.0, otherwise SF Text font');
|
||||||
|
|
||||||
|
Typography typography = new Typography(platform: TargetPlatform.iOS);
|
||||||
|
for (TextTheme textTheme in <TextTheme>[typography.black, typography.white]) {
|
||||||
|
expect(textTheme.display4, hasCorrectFont);
|
||||||
|
expect(textTheme.display3, hasCorrectFont);
|
||||||
|
expect(textTheme.display2, hasCorrectFont);
|
||||||
|
expect(textTheme.display1, hasCorrectFont);
|
||||||
|
expect(textTheme.headline, hasCorrectFont);
|
||||||
|
expect(textTheme.title, hasCorrectFont);
|
||||||
|
expect(textTheme.subhead, hasCorrectFont);
|
||||||
|
expect(textTheme.body2, hasCorrectFont);
|
||||||
|
expect(textTheme.body1, hasCorrectFont);
|
||||||
|
expect(textTheme.caption, hasCorrectFont);
|
||||||
|
expect(textTheme.button, hasCorrectFont);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user