Flutter更改主题颜色报错:type ‘Color‘ is not a subtype of type ‘MaterialColor‘

Bertha 。 2022-10-28 14:23 257阅读 0赞
  1. class MyApp extends StatelessWidget {
  2. @override
  3. Widget build(BuildContext context) {
  4. return MaterialApp(
  5. title: 'Futter App',
  6. debugShowCheckedModeBanner: false,
  7. theme: ThemeData(
  8. //更改主题色为白色
  9. primarySwatch: Colors.white,
  10. visualDensity: VisualDensity.adaptivePlatformDensity,
  11. ),
  12. home: SplashPage(),
  13. );
  14. }
  15. }

在Flutter中,如果我们把默认主题色更改为白色(Colors.white)或黑色(Colors.black),会发生以下错误:

  1. I/flutter ( 6397): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY╞═══════════════════════════════════════════════════════════
  2. I/flutter ( 6397): The following assertion was thrown attaching to the render tree:
  3. I/flutter ( 6397): type 'Color' is not a subtype of type 'MaterialColor'
  4. I/flutter ( 6397): Either the assertion indicates an error in the framework itself, or we should provide
  5. substantially
  6. I/flutter ( 6397): more information in this error message to help you determine and fix the underlying cause.
  7. I/flutter ( 6397): In either case, please report this assertion by filing a bug on GitHub:
  8. I/flutter ( 6397): https://github.com/flutter/flutter/issues/new

原因

查看错误提示,说的是Color不是MaterialColor的子类,打开ThemeData的源码发现,primarySwatch是一个MaterialColor类型的变量,而MaterialColor继承自ColorSwatch。
源码如下

  1. /// A color that has a small table of related colors called a "swatch".
  2. ///
  3. /// The table is indexed by values of type `T`.
  4. ///
  5. /// See also:
  6. ///
  7. /// * [MaterialColor] and [MaterialAccentColor], which define material design
  8. /// primary and accent color swatches.
  9. /// * [material.Colors], which defines all of the standard material design
  10. /// colors.
  11. @immutable
  12. class ColorSwatch<T> extends Color {
  13. /// Creates a color that has a small table of related colors called a "swatch".
  14. ///
  15. /// The `primary` argument should be the 32 bit ARGB value of one of the
  16. /// values in the swatch, as would be passed to the [new Color] constructor
  17. /// for that same color, and as is exposed by [value]. (This is distinct from
  18. /// the specific index of the color in the swatch.)
  19. const ColorSwatch(int primary, this._swatch) : super(primary);
  20. @protected
  21. final Map<T, Color> _swatch;
  22. /// Returns an element of the swatch table.
  23. Color? operator [](T index) => _swatch[index];
  24. @override
  25. bool operator ==(Object other) {
  26. if (identical(this, other))
  27. return true;
  28. if (other.runtimeType != runtimeType)
  29. return false;
  30. return super == other
  31. && other is ColorSwatch<T>
  32. && mapEquals<T, Color>(other._swatch, _swatch);
  33. }
  34. @override
  35. int get hashCode => hashValues(runtimeType, value, _swatch);
  36. @override
  37. String toString() => '${objectRuntimeType(this, 'ColorSwatch')}(primary value: ${super.toString()})';
  38. }

为什么Colors.blue或者其它颜色可以使用呢?
查看Colors的源码发现,white和black其它颜色都是MaterialColor类型。

  1. static const Color black = Color(0xFF000000);
  2. static const Color white = Color(0xFFFFFFFF);
  3. static const MaterialColor blue = MaterialColor(
  4. _bluePrimaryValue,
  5. <int, Color>{
  6. 50: Color(0xFFE3F2FD),
  7. 100: Color(0xFFBBDEFB),
  8. 200: Color(0xFF90CAF9),
  9. 300: Color(0xFF64B5F6),
  10. 400: Color(0xFF42A5F5),
  11. 500: Color(_bluePrimaryValue),
  12. 600: Color(0xFF1E88E5),
  13. 700: Color(0xFF1976D2),
  14. 800: Color(0xFF1565C0),
  15. 900: Color(0xFF0D47A1),
  16. },
  17. );

解决方法

到这里我们知道了,必须传入一个MaterialColor类型的变量才行,既然Flutter没有提供,那我们自己模仿创建一个即可。

  1. void main() {
  2. runApp(MyApp());
  3. }
  4. const MaterialColor white = const MaterialColor(
  5. 0xFFFFFFFF,
  6. const <int, Color>{
  7. 50: const Color(0xFFFFFFFF),
  8. 100: const Color(0xFFFFFFFF),
  9. 200: const Color(0xFFFFFFFF),
  10. 300: const Color(0xFFFFFFFF),
  11. 400: const Color(0xFFFFFFFF),
  12. 500: const Color(0xFFFFFFFF),
  13. 600: const Color(0xFFFFFFFF),
  14. 700: const Color(0xFFFFFFFF),
  15. 800: const Color(0xFFFFFFFF),
  16. 900: const Color(0xFFFFFFFF),
  17. },
  18. );
  19. const MaterialColor black = const MaterialColor(
  20. 0xFFFFFFFF,
  21. const <int, Color>{
  22. 50: const Color(0xFF000000),
  23. 100: const Color(0xFF000000),
  24. 200: const Color(0xFF000000),
  25. 300: const Color(0xFF000000),
  26. 400: const Color(0xFF000000),
  27. 500: const Color(0xFF000000),
  28. 600: const Color(0xFF000000),
  29. 700: const Color(0xFF000000),
  30. 800: const Color(0xFF000000),
  31. 900: const Color(0xFF000000),
  32. },
  33. );
  34. class MyApp extends StatelessWidget {
  35. MyApp() {
  36. final router = FluroRouter();
  37. Routes.configureRoutes(router);
  38. Application.router = router;
  39. }
  40. @override
  41. Widget build(BuildContext context) {
  42. return MaterialApp(
  43. title: 'Flutter App',
  44. debugShowCheckedModeBanner: false,
  45. theme: ThemeData(
  46. primarySwatch: white,
  47. ),
  48. home: SplashPage(),
  49. );
  50. }
  51. }

发表评论

表情:
评论列表 (有 0 条评论,257人围观)

还没有评论,来说两句吧...

相关阅读