How to adapt the dark mode to the shutter (darkmode)

1. Talk nonsense

I don't know what to write. I wanted to write the integration test of flutter. Because I gave it to flutter a while ago_ Deer wrote a set, but he didn't feel much content. He gave up after a few words. (in fact, this article is not much...)

Then write about what you've been doing recently. Yes, the dark mode adaptation mentioned in the article title can also be said to realize the function of night mode. I believe many IOS students have paid more attention recently. After all, IOS 13 pushed an update last month.

The reason for the adaptation is that it is a new feature on IOS 13 and Android 10 systems. The purpose of adaptation is to achieve that the application theme changes with the switching of system theme mode, so as to give users a better consistent experience. Similar to it is the system language setting. When the system sets a language, the text in the application changes accordingly.

Fortunately, flutter also provides an adaptive entrance, so that we can adapt two platforms at a time. Although the millet mix2s in my hand is Android 9, I didn't expect it to fit.

2. Preparation

Now I'll talk about how I'm adapting fluent_ Experience in deer, fluent version 1.9.1.

The first is the problem of standardization. The colors of titles, subtitles, split lines, various backgrounds and the corresponding colors in dark mode must be standardized first. Otherwise, you are not only dazzled by these colors, but also do not have a unified style.

3. Start of adaptation

1. Global adjustment

Fluent provides theme and darktheme entries in materialapp. Let's set the colors and text styles in the two modes. The received themedata covers almost all colors and themes used in material widgets. (Cupertino series components are still being officially adapted, so flutter version 1.9.1 is not supported at the moment.)

By configuring theme and darktheme, we can save a lot of judgment code. For example, my split line has two different colors in different modes. I can't judge it every time I use it. By configuring the global dividertheme, we can directly use divider () or borderside.

ThemeData(
  dividerTheme: DividerThemeData(
  color: isDarkMode ? Colours.dark_line : Colours.line,space: 0.6,thickness: 0.6
  )
 );

Similarly, our page background color and text style can be configured in this way. The following is the final configuration in deer.

ThemeData(
  errorColor: isDarkMode ? Colours.dark_red : Colours.red,brightness: isDarkMode ? Brightness.dark : Brightness.light,primaryColor: isDarkMode ? Colours.dark_app_main : Colours.app_main,accentColor: isDarkMode ? Colours.dark_app_main : Colours.app_main,// Tab指示器颜色
  indicatorColor: isDarkMode ? Colours.dark_app_main : Colours.app_main,// 页面背景色
  scaffoldBackgroundColor: isDarkMode ? Colours.dark_bg_color : Colors.white,// 主要用于Material背景色
  canvasColor: isDarkMode ? Colours.dark_material_bg : Colors.white,// 文字选择色(输入框复制粘贴菜单)
  textSelectionColor: Colours.app_main.withAlpha(70),textSelectionHandleColor: Colours.app_main,textTheme: TextTheme(
  // TextField输入文字颜色
  subhead: isDarkMode ? TextStyles.textDark : TextStyles.text,// Text文字样式
  body1: isDarkMode ? TextStyles.textDark : TextStyles.text,// 这里用于小文字样式
  subtitle: isDarkMode ? TextStyles.textDarkGray12 : TextStyles.textGray12,),inputDecorationTheme: InputDecorationTheme(
  hintStyle: isDarkMode ? TextStyles.textHint14 : TextStyles.textDarkGray14,appBarTheme: AppBarTheme(
  elevation: 0.0,color: isDarkMode ? Colours.dark_bg_color : Colors.white,dividerTheme: DividerThemeData(
  color: isDarkMode ? Colours.dark_line : Colours.line,thickness: 0.6
  )
 );

use:

MaterialApp (
  title: 'Flutter Deer',theme: getTheme(),darkTheme: getTheme(isDarkMode: true),home: TestPage()
 );		

Of course, some widgets are not used, so they are not adapted. You need to look through the source code and comments to know where these colors and themes are used, so this is a laborious process.

In fact, you can also use some "pits", such as another function in the application. The text is different from the main text in font size and color. There are many places to use. It is also troublesome to judge each time. In this way, you can set the unused attributes, such as the subtitle in the above code. This can be achieved by calling theme. Of (context). Texttheme. Subtitle.

Text(
 "文字",style: Theme.of(context).textTheme.subtitle
)

It should be noted that: after all, it is a global configuration. Try to keep it generic without affecting other widgets.

After this part of the configuration is completed, you need to "go to the same while reserving differences".

For example, if the text style you specify is the same as the global configuration, you need to delete it.

If the text color is the same, but the font size is different. Then delete the color configuration information and keep the font size setting:

Text(
 "仅保留不同信息",style: const TextStyle(
 fontSize: 12.0,)
)

Because the source code of text combines global configuration and local configuration through the merge method. The merge is actually implemented by calling copywith. So it can also be written as follows:

Text(
 "仅保留不同信息",style: Theme.of(context).textTheme.body1.copyWith(fontSize: 12.0)
)

Different colors. Because the dark mode is mainly color change, you can consider the "subtitle" scheme above. If there are only a few, some methods can be encapsulated for unified judgment and processing.

2. Local adjustment

After global configuration, most of the adaptation problems have been solved. However, there may be some details to be adjusted, such as icons, individual text colors, and background colors. What is needed at this time is how to judge the dark color mode:

 bool isDarkMode(BuildContext context){
 return Theme.of(context).brightness == Brightness.dark;
 }

The brightness here is the brightness specified in the global configuration themedata above.

Tips:

 /// The foreground color of the [button]'s text and icon.
 ///
 /// If [button] is not [MaterialButton.enabled],the value of
 /// [getDisabledTextColor] is returned. If the button is enabled and
 /// [buttonTextColor] is non-null,then [buttonTextColor] is returned.
 ///
 /// Otherwise the text color depends on the value of [getTextTheme]
 /// and [getBrightness].
 ///
 /// * [ButtonTextTheme.normal]: [Colors.white] is used if [getBrightness]
 /// resolves to [Brightness.dark]. [Colors.black87] is used if
 /// [getBrightness] resolves to [Brightness.light].
 /// * [ButtonTextTheme.accent]: [colorScheme.secondary].
 /// * [ButtonTextTheme.primary]: If [getFillColor] is dark then [Colors.white],/// otherwise if [button] is a [FlatButton] or an [OutlineButton] then
 /// [colorScheme.primary],otherwise [Colors.black].
 Color getTextColor(MaterialButton button) {
 if (!button.enabled)
  return getDisabledTextColor(button);

 if (button.textColor != null)
  return button.textColor;

 switch (getTextTheme(button)) {
  case ButtonTextTheme.normal:
  return getBrightness(button) == Brightness.dark ? Colors.white : Colors.black87;

  case ButtonTextTheme.accent:
  return colorScheme.secondary;

  case ButtonTextTheme.primary: {
  final Color fillColor = getFillColor(button);
  final bool fillIsDark = fillColor != null
   ? ThemeData.estimateBrightnessForColor(fillColor) == Brightness.dark
   : getBrightness(button) == Brightness.dark;
  if (fillIsDark)
   return Colors.white;
  if (button is FlatButton || button is OutlineButton)
   return colorScheme.primary;
  return Colors.black;
  }
 }

 assert(false);
 return null;
 }

3. Function expansion

If you fit the dark mode, you can actually expand this function a little. I thought of the multilingual function in wechat. In multilingual functions, the default option is "follow system". Of course, you can also specify a language.

According to this idea, I added the function of "night mode" in the setting. By default, it also follows the system. Of course, you can also turn it on and off manually.

There is a problem for the time being. Turn on the dark mode on the IOS phone. When I turn off the dark mode in the app, the text in the status bar cannot turn black.

The main problem is that the version of fluent 1.9.1 does not adapt to the uistatusbarstyledarkcontent added by IOS 13 status bar.

Here's a problem for the time being. Turn on the dark mode on the IOS phone. When I turn off the dark mode in the app, the status bar cannot turn black. This problem has also been fed back in the issues of fluent. We look forward to the official adaptation and repair.

These are basically the main contents of adapting dark mode. There is nothing complicated in itself. The Lord is a careful work.

Having said so much, I'll finally show you some adaptive renderings:

For detailed code and implementation details, see fluent_ Deer's code. The design drawings related to dark pattern have also been updated synchronously. I hope it will help you in your study, and I hope you can support us a lot.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>