[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG ioyubvc3-1625618472602)( https://ducafecat.tech/2021/07/07/translation/flutter-build-theme-with-abstract-factory-method/2021-07-07-08-32-18.png )]
Old iron remember to forward, brother old fellow will show more Flutter good text ~ ~ ~
Wechat group ducafecat
Station b https://space.bilibili.com/404904528
original text
https://vbacik-10.medium.com/flutter-build-theme-with-abstract-factory-method-e07df8f730e2
code
https://github.com/VB10/flutter-abstract-theme-manager
reference resources
- https://zeplin.io
text
The most applications have created at least one theme. Maybe this is enough for the first version, but what if the project continues to grow? Let's see how to do it.
We know how important the theme of the project design is, so we will create a theme manager for the project. Let's create a theme manager and this shopping page.
[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-hpytut6q-1625618472604)( https://ducafecat.tech/2021/07/07/translation/flutter-build-theme-with-abstract-factory-method/2021-07-07-07-51-38.png )]
- Design draft
https://adobe.ly/xdfreshfooduikit
First, it needs a page design, such as this page can also be connected to the service. (I created this endpoint for this sample page)
- Background
- App bar - Application Bar
- Search bar - Search Bar
- Search Icon - Search Icon
- Search Text (
- Microphone Icon - ListView
- Product Card - TabBar
- TabBar Icons (
Therefore, we need a palette to use this item. If your design kit has a palette, you can get all the colors in the design kit.
[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-tsnc8xs0-1625618472604)( https://ducafecat.tech/2021/07/07/translation/flutter-build-theme-with-abstract-factory-method/2021-07-07-07-52-54.png )]
Projects must use this palette when new widgets are needed. In fact, with the theme manager, the project will be easier to grow. Finally, we are ready for Hacking time, so we will use both factory method patterns and page atomic design.
Hacking Time
First of all, I prefer to write core features first, which is why we don't redouble our work when the code is completed:
- ITheme abstract classes with different colors and styles
- ThemeFactory class for managing different topics from one point
Factory design is one of the innovative models. This pattern provides advanced objects because the client knows nothing. Now, the pattern creates a custom object so that the project can use the scheme.
Now we know what this structure needs, because we can write an interface that contains both text and color. This interface provides a central viewpoint, so the project needs to. Let's write down these points.
Text theme interface
This is required for every project, as most usage points to the project's text guide. Therefore, after we create the basic style guide, it is very easy to use from the view. Sometimes we need to customize the text style, which doesn't mean you don't use the current style. We can use the copyWith function, so that we can use the view like headline5, or add custom attributes, such as text color.
abstract class ITextTheme { final Color? primaryColor; late final TextTheme data; TextStyle? headline1; TextStyle? headline3; TextStyle? headline4; TextStyle? headline5; TextStyle? headline6; TextStyle? subtitle1; TextStyle? subtitle2; TextStyle? bodyText1; TextStyle? bodyText2; String? fontFamily; ITextTheme(this.primaryColor); }
If your project design has a toolkit, you can use the zeplin tool. This tool gets all text styles in the style guide tab.
https://zeplin.io/
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-scsngm1p-1625618472606)( https://ducafecat.tech/2021/07/07/translation/flutter-build-theme-with-abstract-factory-method/2021-07-07-07-56-06.png )]
Color theme interface
Pointing to items is very important because you know that color is everywhere. So how we manage more projects is easy to control. Each project has a specific color pattern that you must use in your code. If you don't use patterns and projects with a static color code, you won't add multi theme options, and you can't manage color problems.
abstract class IColors { _AppColors get colors; Color? scaffoldBackgroundColor; Color? appBarColor; Color? tabBarColor; Color? tabbarSelectedColor; Color? tabbarNormalColor; Brightness? brightness; ColorScheme? colorScheme; }
I said like a paragraph about zeplin. Again, you can use this and you can all the color attributes.
[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-gxmo0uev-1625618472606)( https://ducafecat.tech/2021/07/07/translation/flutter-build-theme-with-abstract-factory-method/2021-07-07-07-56-45.png )]
Abstract Factory Manager
Manager created for multiple interfaces. This manager creates an instance of ThemeData for the project. Because of this interface, you can create a new topic instance. This new theme only needs a color scheme and so on.
abstract class ITheme { ITextTheme get textTheme; IColors get colors; }
Yes, it looks simple and useful for any project. Finally, we are going to use the core theme drawing operation, so the project can declare a custom theme for this structure. Perhaps these topic interfaces can be improved to a higher level. Now it's enough for this project.
Finally, the factory creator and we need to use the theme manager of this project
abstract class ThemeManager { static ThemeData craeteTheme(ITheme theme) => ThemeData( fontFamily: theme.textTheme.fontFamily, textTheme: theme.textTheme.data, cardColor: theme.colors.colorScheme?.onSecondary, floatingActionButtonTheme: FloatingActionButtonThemeData( foregroundColor: theme.colors.colors.white, backgroundColor: theme.colors.colors.green), appBarTheme: AppBarTheme(backgroundColor: theme.colors.appBarColor), scaffoldBackgroundColor: theme.colors.scaffoldBackgroundColor, colorScheme: theme.colors.colorScheme); }
I plan to have only specific areas, because its project has only two pages, because you know this sample. You must create other areas of the text style and color scheme area. Let's create a custom theme with this structure, and we'll show this advantage.
Ligh Theme on Project
In fact, we have a structure and project on how to create a light theme.
class AppThemeLight extends ITheme { @override late final ITextTheme textTheme; AppThemeLight() { textTheme = TextThemeLight(colors.colors.mediumGrey); } @override IColors get colors => LightColors(); }
Of course, dark themes are created like this, so just changing style guidelines and projects can be used directly. You can access the dark theme code here.
TextTheme Light needs to draw the basic color of the default color of the text, and the light color has been created from the zeplin style.
class TextThemeLight implements ITextTheme { @override late final TextTheme data; @override TextStyle? bodyText1; @override TextStyle? bodyText2; @override TextStyle? headline1; @override TextStyle? headline3; @override TextStyle? headline4; @override TextStyle? headline5; @override TextStyle? headline6; @override TextStyle? subtitle1; @override TextStyle? subtitle2; final Color? primaryColor; TextThemeLight(this.primaryColor) { data = TextTheme( headline6: TextStyle(fontSize: 20, fontWeight: FontWeight.normal), subtitle1: TextStyle(fontSize: 16.0), ).apply(bodyColor: primaryColor); fontFamily = GoogleFonts.arvo().fontFamily; } @override String? fontFamily; }
Well, if we want to see an example of a light theme, it shows this.
class LightColors implements IColors { @override final _AppColors colors = _AppColors(); @override ColorScheme? colorScheme; @override Color? appBarColor; @override Color? scaffoldBackgroundColor; @override Color? tabBarColor; @override Color? tabbarNormalColor; @override Color? tabbarSelectedColor; LightColors() { appBarColor = colors.white; scaffoldBackgroundColor = colors.white; tabBarColor = colors.green; tabbarNormalColor = colors.lighterGrey; tabbarSelectedColor = colors.darkerGrey; colorScheme = ColorScheme.light() .copyWith(onPrimary: colors.green, onSecondary: colors.white); brightness = Brightness.light; } @override Brightness? brightness; }
Sometimes you need to prepare style because you don't have enough style knowledge. At this time, you can use a color scheme instance for your project, so you can get the material color scheme, so you can add your custom business layer.
The Light theme is ready to use. The project only needs the topic factory method, and you can write an instance of this class. This is acceptable for all elements of the project color.
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: '@VB10', theme: ThemeManager.craeteTheme(AppThemeLight()), home: SampleView(), ); } }
Yes, we can start drawing on the search results screen. In particular, don't forget this method. Let's see how to create a topic instance for this project.
abstract class ThemeManager { static ThemeData craeteTheme(ITheme theme) => ThemeData( fontFamily: theme.textTheme.fontFamily, textTheme: theme.textTheme.data, cardColor: theme.colors.colorScheme?.onSecondary, tabBarTheme: TabBarTheme( indicator: BoxDecoration(), labelColor: theme.colors.tabbarSelectedColor, unselectedLabelColor: theme.colors.tabbarNormalColor, ), floatingActionButtonTheme: FloatingActionButtonThemeData( foregroundColor: theme.colors.colors.white, backgroundColor: theme.colors.colors.green), appBarTheme: AppBarTheme(backgroundColor: theme.colors.appBarColor), scaffoldBackgroundColor: theme.colors.scaffoldBackgroundColor, colorScheme: theme.colors.colorScheme); }
Now the project directly depends on all theme instances, because we only change the theme value, and the project will go to a new color scheme. In addition, the project never needs any code design time. This means that your project design has completed all the work
Feature Page
We have a topic instance, so just call this instance and everything is ready. First, drawing a page tree is very important to better understand.
Now the coding is very simple because we know how to draw this. In particular, you pay great attention to coding time, so you can always use topic instances in your page design. The project has a theme design because this variable can be called directly. For example, any page can require a background color, so we don't need to write over and over again because we have examples of topics that use this situation.
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-5momys1z-1625618472609)( https://ducafecat.tech/2021/07/07/translation/flutter-build-theme-with-abstract-factory-method/2021-07-07-08-01-02.png )]
Yes, we are going to develop another topic manager and widget tree structure. First, let's create a tab view structure in the code.
final List<MapEntry<Widget, IconData>> _pages = [ MapEntry(SampleView(), Icons.search), MapEntry(Container(), Icons.search), MapEntry(Container(), Icons.search), MapEntry(Container(), Icons.search), ]; @override Widget build(BuildContext context) { return DefaultTabController( length: _pages.length, child: Scaffold( floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, floatingActionButton: floatingActionButton(context), bottomNavigationBar: _bottomAppBar(), body: TabBarView(children: _pages.map((e) => e.key).toList()), )); }
In fact, we see the fab button. We need a custom color because the color is created for blue, but we add this custom code to the theme and only write a floating operation button. This button reads the own property in the topic instance from the context.
I said you don't need extra code to call this widget directly.
FloatingActionButton floatingActionButton(BuildContext context) { return FloatingActionButton( child: Icon(Icons.add), onPressed: () {}, ); }
After that, let's show the search results page design. We talked about the impact of this page design on the article. This is very important for flutter planning. You need to keep thinking about this tree structure. You can use the idea of this widget tree to make a great page.
@override Widget build(BuildContext context) { return Scaffold( appBar: buildAppBar(context), body: Padding( padding: EdgeInsets.only(top: MediaQuery.of(context).size.width * 0.08), child: Column( children: [ textFieldSearchCard(context), Expanded(child: buildGridViewBody()), ], ), ), ); }
This shows a lot of problems. Let's look at some widgets to see how to use themes. Our design has a custom search bar with search icons and microphone buttons.
Widget textFieldSearch(BuildContext context) { return TextField( decoration: InputDecoration( border: InputBorder.none, prefixIcon: Icon(Icons.search_sharp, color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.5)), suffixIconConstraints: BoxConstraints(maxHeight: 30), suffixIcon: FloatingActionButton( onPressed: () {}, mini: true, child: Icon(Icons.mic_sharp), )), ); }
This code design does not require additional code. You can use what you need here from the topic context. Let's take a look at an example of a text style:
Text buildTextSub(BuildContext context) { return Text( items.searchResults, style:Theme.of(context).textTheme.headline6?.copyWith( letterSpacing: -0.2, fontWeight: FontWeight.w400, ), ); }
As you can see, this is a very simple and easy to manage code. I just added some custom code and completed all the work.
You can see the item properties, which may have an important relationship with comments. If you have all constant value classes and only want to create constant values, you can add the @ immutable annotation after the class obtains security capabilities.
@immutable class AppTextItems { final String searchResults = 'Search Results'; final String brocoliText = 'Broccoli'; }
Yes, the project may be a sample for understanding the architecture, but powerful code should always be written.
Yees project has been completed. If you want to change a theme, such as darkness, we just need to change this instance to darkness, and then it's OK.
[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-bxihxyfu-1625618472610)( https://ducafecat.tech/2021/07/07/translation/flutter-build-theme-with-abstract-factory-method/2021-07-07-08-04-45.png )]
Therefore, we adopt abstract factory design capability and manageable code design. It sounds good for developing forces because flutter can improve modes and special angles.
[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-uu1qik6h-1625618472611)( https://ducafecat.tech/2021/07/07/translation/flutter-build-theme-with-abstract-factory-method/manage-theme-with-factory-design.gif )]
It's done. Now we can directly implement our own projects and manage everything. On the other hand, this project does not need how to create new topic knowledge, because you know we create interfaces. Different themes just fit these interfaces, and then everything is done.
In fact, the main goal of this article is how to use this pattern in topic instances, so this knowledge is very important to your development life.
Thank you for reading "thank you for reading" for your life and health "
https://github.com/VB10/flutter-abstract-theme-manager
© Cat brother
https://ducafecat.tech/
https://github.com/ducafecat
Previous period
Open Source
GetX Quick Start
https://github.com/ducafecat/getx_quick_start
News client
https://github.com/ducafecat/flutter_learn_news
Translation of strapi manual
https://getstrapi.cn
Wechat discussion group ducafecat
Series collection
translation
https://ducafecat.tech/categories/%E8%AF%91%E6%96%87/
Open source project
https://ducafecat.tech/categories/%E5%BC%80%E6%BA%90/
Basics of Dart programming language
https://space.bilibili.com/404904528/channel/detail?cid=111585
Introduction to Flutter zero Foundation
https://space.bilibili.com/404904528/channel/detail?cid=123470
Flutter actual combat news client from scratch
https://space.bilibili.com/404904528/channel/detail?cid=106755
Fluent component development
https://space.bilibili.com/404904528/channel/detail?cid=144262
Flutter Bloc
https://space.bilibili.com/404904528/channel/detail?cid=177519
Flutter Getx4
https://space.bilibili.com/404904528/channel/detail?cid=177514
Docker Yapi
https://space.bilibili.com/404904528/channel/detail?cid=130578