1. Введение
Класс Theme применяет тему к дочерним элементам управления, а Theme описывает выбор цвета и типографики приложения. Существует два вида темы: глобальная тема и локальная тема. Глобальная тема — это тема, созданная корневым приложением MaterialApp; локальная тема используется для переопределения глобальной темы в определенной области приложения.
Введение на официальном сайте Google:API.flutter.Dev/flutter/туалет…
Конструктор
Theme({Key key,
@required ThemeData data,
bool isMaterialAppTheme: false,
@required Widget child })
- Данные ThemeData: содержат стили типографики, такие как цвета и шрифты для темы Material.
- isMaterialAppTheme: значение по умолчанию — false, указывающее, является ли тема стилем материального дизайна.
- ребенок: дочерний элемент управления.
отношения наследования
Объект -> Диагностируемый -> Диагностируемое дерево -> Виджет -> Виджет без состояния -> Тема.
2. Тематические данные
Из конструктора Theme нетрудно увидеть, что Flutter использует ThemeData для сохранения такой информации, как темы и стили общих приложений, поэтому продолжаем смотреть официальные документы и изучать, какие точки знаний содержатся в ThemeData.
Наследственные отношения: Object -> Diagnosticable -> ThemeData
Конструктор:
ThemeData({Brightness brightness,
MaterialColor primarySwatch,
Color primaryColor,
Brightness primaryColorBrightness,
Color primaryColorLight,
Color primaryColorDark,
Color accentColor,
Brightness accentColorBrightness,
Color canvasColor,
Color scaffoldBackgroundColor,
Color bottomAppBarColor,
Color cardColor,
Color dividerColor,
Color focusColor,
Color hoverColor,
Color highlightColor,
Color splashColor,
InteractiveInkFeatureFactory splashFactory,
Color selectedRowColor,
Color unselectedWidgetColor,
Color disabledColor,
Color buttonColor,
ButtonThemeData buttonTheme,
Color secondaryHeaderColor,
Color textSelectionColor,
Color cursorColor,
Color textSelectionHandleColor,
Color backgroundColor,
Color dialogBackgroundColor,
Color indicatorColor,
Color hintColor,
Color errorColor,
Color toggleableActiveColor,
String fontFamily,
TextTheme textTheme,
TextTheme primaryTextTheme,
TextTheme accentTextTheme,
InputDecorationTheme inputDecorationTheme,
IconThemeData iconTheme,
IconThemeData primaryIconTheme,
IconThemeData accentIconTheme,
SliderThemeData sliderTheme,
TabBarTheme tabBarTheme,
CardTheme cardTheme,
ChipThemeData chipTheme,
TargetPlatform platform,
MaterialTapTargetSize materialTapTargetSize,
PageTransitionsTheme pageTransitionsTheme,
AppBarTheme appBarTheme,
BottomAppBarTheme bottomAppBarTheme,
ColorScheme colorScheme,
DialogTheme dialogTheme,
FloatingActionButtonThemeData floatingActionButtonTheme,
Typography typography,
CupertinoThemeData cupertinoOverrideTheme,
SnackBarThemeData snackBarTheme,
BottomSheetThemeData bottomSheetTheme })
Из его конструктора нетрудно увидеть, что он в основном сохраняет такие настройки, как различные цвета, шрифты и стили значков. Из-за того, что атрибутов слишком много, мы выберем некоторые часто используемые, чтобы поговорить о них:
-
яркость - Тип яркости, общая яркость темы приложения. Используется для виджетов, таких как кнопки, чтобы определить, какой цвет выбрать, когда не используется primaryColor или accentColor. Когда яркость ниже, холст, карта и основные цвета темнее. Когда яркость светлая, цвет холста и карты яркий, а темнота основного цвета меняется в зависимости от яркости основного цвета. При низкой яркости основной цвет (primaryColor) плохо контрастирует с цветами карты и холста; при низкой яркости используйте для контраста белый или ярко-синий цвет.
-
primarySwatch — тип MaterialColor, цвет, определенный в теме «Материал», имеет образцы цвета для десяти цветовых оттенков. Чем больше значение, тем темнее цвет.10 допустимых индексов: 50, 100, 200, …, 900. По умолчанию принимается среднее значение 500.
-
primaryColor - Тип цвета, цвет фона основной части приложения (ToolBar, Tabbar и т.д.)
-
primaryColorBrightness — тип яркости, яркость primaryColor, используемая для определения цвета текста и значков (например, текста на панели инструментов), установленных выше primaryColor.
-
PrivateColorlight - более легкая версия типа цвета, первичный цвет
-
primaryColorDark — тип цвета, более темная версия primaryColor.
-
AccentColor — тип цвета, цвет переднего плана (кнопки, текст, наложение краевых эффектов и т. д.)
-
AccentColorBrightness — тип яркости, яркость AccentColor. Используется для определения цвета текста и значков поверх AccentColor (например, значков на плавающих кнопках действий).
-
canvasColor — тип цвета, цвет по умолчанию для материала MaterialType.canvas.
-
scaffoldBackgroundColor — тип цвета, как цвет материала по умолчанию в разделе Scaffold, используемый для цвета фона приложений materia или страниц в приложении.
-
bottomAppBarColor — тип цвета, цвет по умолчанию для bottomAppBarColor. Это можно переопределить, указав BottomAppBar.color.
-
cardColor - Тип цвета, цвет Материала, используемого на карточке (Card).
-
DividerColor — тип цвета, цвет разделителей (Dividers) и разделителей всплывающих окон (PopupMenuDividers), также используемый между строками ListTiles и DataTables. Чтобы создать подходящую границу с использованием этого цвета, рассмотрите Divider.createBorderSide.
-
highlightColor — тип цвета, цвет выделения, используемый для анимации брызг чернил или для обозначения того, что меню выбрано.
-
splashColor - Тип цвета, цвет чернильного брызга
-
splashFactory — тип InteractiveInkFeatureFactory, определяющий внешний вид брызг чернил, создаваемых InkWall и InkResponse.
-
selectedRowColor — тип цвета, цвет, используемый для выделения выбранной строки.
-
unselectedWidgetColor — тип цвета, цвет, используемый, когда виджет находится в неактивном (но включенном) состоянии. Например, снятый флажок. Часто противопоставляется AccentColor.
-
disabledColor - Тип цвета, цвет отключенных виджетов, вне зависимости от их состояния. Например, отключенный флажок (который можно поставить или снять).
-
buttonColor — тип цвета, цвет заливки по умолчанию, используемый RaisedButtons в материале.
-
buttonTheme — тип ButtonThemeData, который определяет конфигурацию по умолчанию для виджетов кнопок, таких как RaisedButton и FlatButton.
-
SecondaryHeaderColor — тип цвета, цвет заголовка PaginatedDataTable при наличии выделенной строки.
-
textSelectionColor - тип Color, цвет, которым выделяется текст в текстовом поле (например, TextField).
-
cursorColor — тип цвета, цвет курсора в текстовых полях в стиле материала (таких как TextField).
-
TextselectionHandleColor - Ручка типа цвета для регулировки цвета выбранной текущей текстовой части.
-
backgroundColor - тип Color, цвет, контрастирующий с основным цветом (например, используемый для остальной части индикатора выполнения).
-
dialogBackgroundColor - Тип цвета, Тип цвета, цвет фона элемента Диалог
-
индикаторColor - Type Color, цвет индикатора, выбранный опцией в TabBar.
-
hintColor — тип цвета, цвет, используемый для текста подсказки или текста-заполнителя, например, в TextField.
-
errorColor — тип цвета, цвет, используемый для ошибок проверки ввода, например, в TextField.
-
toggleableActiveColor — тип цвета, цвет, используемый для выделения активного состояния переключаемых виджетов, таких как Switch, Radio и Checkbox.
-
fontFamily - Тип строки, тип шрифта
-
textTheme - тип TextTheme, цвет текста для контраста с картой и холстом
-
primaryTextTheme — тип TextTheme, тема текста, контрастирующая с основным цветом.
-
AccentTextTheme — тип TextTheme, тема текста, контрастирующая с цветом акцента.
-
inputDecorationTheme — тип InputDecorationTheme, на котором основаны значения InputDecoration по умолчанию для InputDecorator, TextField и TextFormField.
-
iconTheme — тип IconThemeData, тема значков, которая контрастирует с цветами карты и холста.
-
primaryIconTheme — тип IconThemeData, тема значка, контрастирующая с основным цветом.
-
AccentIconTheme — тип IconThemeData, тема значка, которая контрастирует с цветом переднего плана.
-
sliderTheme — тип SliderThemeData, тип SliderThemeData, используемый для рендеринга цвета и формы слайдера.
-
tabBarTheme — тип TabBarTheme, тема для настройки размера, формы и цвета индикатора панели вкладок.
-
chipTheme — тип ChipThemeData, используемый для цвета и стиля чипа.
-
platform — тип TargetPlatform, виджет должен адаптироваться под целевую платформу.
-
materialTapTargetSize — тип MaterialTapTargetSize, настраивает размер теста нажатия для конкретной детали материала.
-
pageTransitionsTheme — тип PageTransitionsTheme, переход MaterialPageRoute по умолчанию для каждой целевой платформы.
-
Цветовая схема Тип ColorScheme, набор из 13 цветов, которые можно использовать для настройки цветовых свойств большинства компонентов.
-
typography — Тип типографики, используемый для настройки значений цветовой и геометрической текстовой темы для TextTheme, primaryTextTheme и AccentTextTheme.
Три, Тема метода
Это статический метод. Дочерние элементы управления получают объект ThemeData для текущей темы с помощью Theme.of, а когда элемент управления использует Theme.of, если тема изменяется позже, он автоматически перестраивается, чтобы можно было применить изменения. Мы можем просмотреть цветовую схему текущего приложения через Theme.of.
Код метода ThemeData.of:
ThemeData of (
BuildContext context, {
bool shadowThemeOnly: false
})
Данные ThemeData поступают из самого последнего экземпляра Theme для данного контекста. Если данный контекст содержится в виджете Localizations, который предоставляет MaterialLocalizations, возвращаемые данные будут локализованы в соответствии с ближайшими доступными MaterialLocalizations. По умолчанию используется new ThemeData.fallback, если в данном контексте сборки нет темы.
Пример использования следующий:
@override
Widget build(BuildContext context) {
return Text(
'Theme Example',
style: Theme.of(context).textTheme.title,
);
}
Здесь мы уже знаем, как установить тему флаттера, во флаттере тема делится на глобальную тему и локальную тему. Далее мы объясним применимые сценарии и различия между этими двумя методами.
4. Глобальные темы
При создании глобальной темы приложения мы можем предоставить объект ThemeData для MaterialApp.Если конструктор не устанавливает ThemeData, Flutter создаст тему по умолчанию. Давайте попрактикуемся и напишем простой пример настройки глобальной темы:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
brightness: Brightness.light, //指定亮度主题,有白色/黑色两种可选。
primaryColor: Colors.blue[800], //这里我们选蓝色为基准色值。
accentColor: Colors.lightBlue[100]), //这里我们选浅蓝色为强调色值。
home: ThemeTest(),
);
}
}
class ThemeTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ThemeTest"), //页面标题
),
body: Container(
color: Theme.of(context).primaryColor, //内容背景颜色
margin: EdgeInsets.all(100.0),
padding: EdgeInsets.all(10.0),
child: Text(
"MaterialApp Theme Color", //内容文本
style: TextStyle(
fontSize: 20, color: Theme.of(context).accentColor), //内容文本颜色,引用的是accentColor。
textAlign: TextAlign.center,
),
),
);
}
}
Схема эффекта выглядит следующим образом:
5. Местные темы
Локальные темы используются в определенных областях приложения для переопределения глобальной темы. После того, как мы определим тему, мы можем использовать ее с помощью метода Theme.of(context) в методе сборки виджета. Theme.of(context) просматривает дерево виджетов и возвращает ближайшую тему в дереве. Если над виджетом есть отдельное определение локальной темы, возвращает значение темы; если нет, возвращает глобальную тему приложения. Расскажем об основных нескольких способах создания:
5.1 Воссоздание объекта темы
Пересоздав Theme, создайте экземпляр, заново создайте ThemeData и назначьте его данным. Затем укажите дочерний виджет и передайте ThemeData виджету Theme.Код выглядит следующим образом:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
brightness: Brightness.light, //指定亮度主题,有白色/黑色两种可选。
primaryColor: Colors.blue[800], //这里我们选蓝色为基准色值。
accentColor: Colors.lightBlue[100]), //这里我们选浅蓝色为强调色值。
home: Theme(
data: ThemeData(accentColor: Colors.yellow),
child: ThemeTest())); //创建局部主题,将accentColor设置为黄色
}
}
class ThemeTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ThemeTest"),
),
body: Container(
color: Theme.of(context).primaryColor,
margin: EdgeInsets.all(100.0),
padding: EdgeInsets.all(10.0),
child: Text(
"MaterialApp Theme Color",
style: TextStyle(
fontSize: 20, color: Theme.of(context).accentColor), //应用局部主题颜色
textAlign: TextAlign.center,
)),
);
}
}
Схема эффекта выглядит следующим образом:
Частичная тема не действует
Здесь есть небольшой нюанс, нам нужно установить локальную тему в виджете родительского слоя виджета, это вступит в силу; если мы используем его непосредственно в виджете, указанном дочерним атрибутом локальной темы, мы получим глобальная тема системы. .
Следующий пример:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
brightness: Brightness.light, //指定亮度主题,有白色/黑色两种可选。
primaryColor: Colors.blue[800], //这里我们选蓝色为基准色值。
accentColor: Colors.white), //设置为白色。
home: ThemeTest(),
);
}
}
class ThemeTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ThemeTest"),//页面标题
),
body: Container(
color: Theme.of(context).primaryColor,
margin: EdgeInsets.all(100.0),
padding: EdgeInsets.all(10.0),
child: Theme(
data: ThemeData(accentColor: Colors.red), //设置红色
//创建accentColor 为绿色的局部主题,若局部主题Theme 的Child 是 Text,则Text引用局部主题色不会生效,拿到的还是局部Themes上层的值,即全局主题的值。
child: Text(
"MaterialApp Theme Color",
style: TextStyle(
fontSize: 20, color: Theme.of(context).accentColor), //应用主题色
textAlign: TextAlign.center,
))),
);
}
}
Схема эффекта выглядит следующим образом:
Как вы можете видеть на снимке экрана, цвет, отображаемый текстом, по-прежнему белый и не изменился на ожидаемый нами красный цвет, поэтому нам нужно уделять этому особое внимание при его использовании.
5.2 Расширение родительской темы
В дополнение к созданию объекта Theme для использования частичной темы, мы можем использовать для этого метод copyWith.В этом случае, когда мы изменяем родительскую тему, нам не нужно переопределять все свойства темы, нам нужно только укажите свойства, которые мы хотим изменить.
Изменить оригинал:
data: ThemeData(accentColor: Colors.yellow)
Измените его на:
Theme.of(context).copyWith(accentColor: Colors.yellow)
Таким образом, в дополнение к изменению акцентного цвета на указанное значение нашей локальной темы, другие атрибуты могут по-прежнему использовать значение атрибута предыдущей темы, вместо того, чтобы стать системным значением по умолчанию.
5.3 Установка различных тем в зависимости от платформы устройства
В дополнение к двум вышеупомянутым методам мы также можем предоставить различные темы в зависимости от типа платформы устройства (iOS, Android и Fuchsia):
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final ThemeData iOSTheme = ThemeData(
brightness: Brightness.light,
primaryColor: Colors.grey[600],
accentColor: Colors.white,
);
final ThemeData androidTheme = ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.yellow[300],
accentColor: Colors.deepPurple[800],
);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
brightness: Brightness.light,
primaryColor: Colors.grey[100],
accentColor: Colors.white,
),
home: Theme(
data: defaultTargetPlatform == TargetPlatform.android
? androidTheme
: iOSTheme,
child: ThemeTest()),
);
}
}
class ThemeTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ThemeTest"),
),
body: Container(
color: Theme.of(context).primaryColor,
margin: EdgeInsets.all(100.0),
padding: EdgeInsets.all(10.0),
child: Text(
"MaterialApp Theme Color",
style:
TextStyle(fontSize: 20, color: Theme.of(context).accentColor),
textAlign: TextAlign.center,
)),
);
}
}
Боковые рендеры Android:
Рендеринг на iOS:
6. Резюме
В этой статье в основном описываются некоторые распространенные методы и свойства Theme. В то же время также даны более подробные практические примеры для методов настройки глобальных тем, локальных тем и различных тем платформы. Настройка темы во флаттере относительно гибкая, и вы можете много практиковаться.
автор
xiaosongzeem |