我如何将 Flutter 中的所有设计元素隔离到一个 ThemeData 类...有任何策略 os 解决方案吗?
Posted
技术标签:
【中文标题】我如何将 Flutter 中的所有设计元素隔离到一个 ThemeData 类...有任何策略 os 解决方案吗?【英文标题】:How i can isolate all design elements in Flutter to one ThemeData class ... Have any strategy os solution? 【发布时间】:2021-07-13 10:13:43 【问题描述】:如何将 Flutter 中的所有设计元素隔离到一个 ThemeData 类文件中。颜色,装饰,配色方案。我尝试将我的代码分离为设计、页面、业务/类似...
myThemeData 文件:
import 'package:flutter/material.dart';
class MyTheme
final BuildContext context;
MyTheme(this.context);
ColorScheme get myColorSheme
return Theme.of(context).colorScheme.copyWith(
primary: Colors.red,
onPrimary: Colors.black,
primaryVariant: Colors.orange,
background: Colors.red,
onBackground: Colors.black,
secondary: Colors.red,
onSecondary: Colors.white,
secondaryVariant: Colors.deepOrange,
error: Colors.black,
onError: Colors.white,
surface: Colors.white,
onSurface: Colors.black,
brightness: Brightness.light,
);
ThemeData get myThemeData
return ThemeData(
buttonTheme: ButtonThemeData(
textTheme: ButtonTextTheme.primary,
),
hintColor: Colors.red,
brightness: Brightness.dark,
colorScheme: myColorSheme,
);
static InputDecoration inputDecoration(String hintText, Icon icon)
return InputDecoration(
hintStyle: MyTheme.hintTextStyle,
hintText: hintText,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white, width: 3),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white54, width: 1),
),
prefixIcon:
IconTheme(data: IconThemeData(color: Colors.white), child: icon),
);
static TextStyle get hintTextStyle
return TextStyle(
fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white30);
static TextStyle get textFieldStyle
return TextStyle();
static TextStyle get logoTextStyle
return TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
);
结果我有错误
════════小部件库捕获的异常═════════════════════════════════════ ═ 在构建 MyApp(dirty, state: _MyAppState#84f70) 时抛出了以下断言: 断言失败: C:\…\material\theme_data.dart:316 colorScheme?.brightness == null ||亮度 == 空 || colorScheme!.brightness == 亮度 不是真的
相关的导致错误的小部件是 我的应用 lib\main.dart:10 抛出异常时,这是堆栈 C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49 throw C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3 assertFailed 包/flutter/src/material/theme_data.dart 316:106 新 包/服务/UI/Theme.dart 27:12 获取 myThemeData 包/服务/main.dart 24:38 构建 ... ══════════════════════════════════════════════════ ══════════════════════════════
【问题讨论】:
【参考方案1】:在定义自己的主题数据时使用copyWith
方法很好。大多数时候使用不使用所有字段,并且某些字段是强制性的。
所以做这样的事情
For Dark theme
ThemeData get myThemeData
return ThemeData.dark().copyWith()(
buttonTheme: ButtonThemeData(
textTheme: ButtonTextTheme.primary,
),
hintColor: Colors.red,
brightness: Brightness.dark,
colorScheme: myColorSheme,
);
For Light theme
ThemeData get myThemeData
return ThemeData.light().copyWith()(
buttonTheme: ButtonThemeData(
textTheme: ButtonTextTheme.primary,
),
hintColor: Colors.red,
brightness: Brightness.dark,
colorScheme: myColorSheme,
);
您还可以看到我如何在我的一个项目中使用 ThemeData,如下所示
我的黑暗/黑色主题
ThemeData blackTheme(BuildContext context)
return ThemeData.dark().copyWith(
snackBarTheme: SnackBarThemeData(
backgroundColor: selectedPrimaryColor,
actionTextColor: greyColor,
contentTextStyle: const TextStyle(color: Colors.white),
shape: const ContinuousRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
),
accentColor: selectedPrimaryColor,
cardColor: Colors.black,
primaryColor: Colors.black,
brightness: Brightness.dark,
primaryColorLight: Colors.black,
scaffoldBackgroundColor: Colors.black,
dialogBackgroundColor: Colors.black,
canvasColor: Colors.black,
floatingActionButtonTheme: FloatingActionButtonThemeData(
foregroundColor: Colors.white,
backgroundColor: selectedPrimaryColor,
),
dialogTheme: DialogTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
textSelectionTheme: TextSelectionThemeData(
cursorColor: selectedPrimaryColor,
selectionHandleColor: selectedPrimaryColor,
selectionColor: darken(selectedPrimaryColor, 50),
),
textTheme: const TextTheme(
headline5: TextStyle(color: Colors.white),
headline1: TextStyle(color: Colors.white),
headline2: TextStyle(color: Colors.white),
bodyText1: TextStyle(color: Colors.white),
bodyText2: TextStyle(color: Colors.white),
caption: TextStyle(color: Colors.white),
subtitle1: TextStyle(color: Colors.white),
subtitle2: TextStyle(color: Colors.white),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states)
if (states.contains(MaterialState.disabled))
return greyColor;
return selectedPrimaryColor; // Defer to the widget's default.
,
),
/* elevation: MaterialStateProperty.resolveWith<double>(
(Set<MaterialState> states)
if (states.contains(MaterialState.disabled))
return 0;
return 0; // Defer to the widget's default.
,
),*/
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states)
if (states.contains(MaterialState.disabled))
return greyColor;
return selectedPrimaryColor; // Defer to the widget's default.
,
),
),
),
bottomSheetTheme: const BottomSheetThemeData(
backgroundColor: Colors.black,
),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states)
if (states.contains(MaterialState.disabled))
return greyColor;
return Colors.white; // Defer to the widget's default.
,
),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states)
if (states.contains(MaterialState.disabled))
return greyColor;
return Colors.black; // Defer to the widget's default.
,
),
),
),
);
我的轻主题
ThemeData lightTheme(BuildContext context)
// debugPrint(selectedPrimaryColor.toString());
return ThemeData.light().copyWith(
canvasColor: Colors.white,
cardColor: const Color.fromARGB(255, 255, 255, 255),
accentColor: selectedPrimaryColor,
toggleableActiveColor: selectedPrimaryColor,
primaryColor: selectedPrimaryColor,
dialogTheme: const DialogTheme(
titleTextStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
)),
snackBarTheme: SnackBarThemeData(
backgroundColor: selectedPrimaryColor,
actionTextColor: Colors.white,
contentTextStyle: const TextStyle(
color: Colors.white,
),
shape: const ContinuousRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
),
brightness: Brightness.light,
bottomSheetTheme: BottomSheetThemeData(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
textTheme: TextTheme(
headline5: const TextStyle(color: Colors.black),
headline1: const TextStyle(color: Colors.black),
headline2: const TextStyle(color: Colors.black),
bodyText1: const TextStyle(color: Colors.black),
bodyText2: const TextStyle(color: Colors.black),
caption: const TextStyle(color: Colors.black),
subtitle1: const TextStyle(color: Colors.black),
subtitle2: TextStyle(color: Colors.grey[200]),
),
textSelectionTheme: TextSelectionThemeData(
cursorColor: selectedPrimaryColor,
selectionHandleColor: selectedPrimaryColor,
selectionColor: lighten(selectedPrimaryColor, 65),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states)
if (states.contains(MaterialState.disabled))
return greyColor;
return selectedPrimaryColor; // Defer to the widget's default.
,
),
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states)
if (states.contains(MaterialState.disabled))
return Colors.black;
return selectedPrimaryColor; // Defer to the widget's default.
,
),
),
),
floatingActionButtonTheme:
Theme.of(context).floatingActionButtonTheme.copyWith(
backgroundColor: selectedPrimaryColor,
foregroundColor: Colors.white,
),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states)
if (states.contains(MaterialState.disabled))
return greyColor;
return selectedPrimaryColor;
,
),
),
),
);
【讨论】:
萨克斯。据我了解,copyWith(...) 仅用于部分更改您想要的内容? 是的。但如果你决定走其他路。从头开始定义一切。然后你应该提供所有必填字段。 Kop kop rakhme(非常非常 Thax)对不起我的英语! 如果可能? 1模式问题!我如何理解 MaterialApp 有 2 种模式 Dakr 和 light!我可以创建 MyMode 吗?以及如何更好地重新实现?以上是关于我如何将 Flutter 中的所有设计元素隔离到一个 ThemeData 类...有任何策略 os 解决方案吗?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 如何访问 ListView.builder 中的一个元素?