[Front-end tutorial] The most detailed in the whole network! The practice of Diablo mode in Trip.com App

1. Background

In 2019, with the launch of iOS 13 and Android Q, Apple and Google simultaneously launched the main features of the dark mode, respectively Dark Mode (iOS) / Dark Theme (Android), hereinafter we collectively referred to as Dark Theme. In the preliminary research, we found that 66% of iOS 13 users choose to open Dark Theme, which shows that users love and expect the dark mode.

So what are the benefits of Dark Theme?

  • More power-saving, most modern mobile phones are OLED screens (the OLED screen does not emit light under black, which is more power-saving), and the Dark Theme has lower energy consumption;

  • Provide a consistent user experience, when users switch from the Dark Theme environment to our App, they can still enjoy the tranquility of black and avoid the stimulus caused by the bright white;

  • Improve the brand image, follow up on the new features of the system in time, in addition to enjoying the new features and bring goodness, you can also get the recommendation opportunities of Apple Store and Google Play to enhance the overall brand image

  • Improve visibility for users with amblyopia and those who are sensitive to strong light, allowing users to easily use the app in a dark environment.

Next, we introduce the practice of Dark Theme in Trip.com App from three angles of visual design, implementation scheme and development efficiency.

Second, visual design

Dark mode is a brand new design style, non-simple color shading. We attribute the design concept to three main points and introduce our overall design ideas.

2.1 Three main points

1) The higher the element level, the lighter the surface color

The UI visual hierarchy is dedicated to presenting product content in a way that users can quickly understand. How do you ensure that the visual hierarchy is still valid under Dark Theme? In Light mode, we use a white card with a projection to simulate the sense of spatial depth in the real world, while switching to Dark mode, we need to express the height through a lighter color surface. The higher the level, the closer to the light source, the lighter the surface color.

image

2) Reduce saturation and improve readability

When designing Dark Theme, try to avoid using highly saturated colors, because these colors will produce visual jitter on a dark background, causing fatigue to the human eye. Taking Trip.com's brand blue as an example, if the color is not adjusted and displayed directly on a dark background, not only the clarity of the information is reduced, but also the recognition effort is increased. This is obviously not what we want, so under Dark Theme we choose lower saturation colors to achieve better readability.

image

3) Increase contrast and improve usability

According to the WCAG2.0 AA design standard, the visual presentation of text and text images must have a contrast ratio of at least 4.5: 1. The selection of white text on dark surfaces does not meet the AA standard.

image

2.2 Design plan

Following the above design points, we have developed Trip.com's color mapping and illustration design.

2.2.1 Color mapping scheme

In order to standardize the management of color libraries and ensure the consistent understanding of products, design, and development, we use the most intuitive way to name colors. This method not only unified the color naming of Light and Dark, but also reduced the difficulty of communication between all parties. The specific mapping effect is as follows:

image

The colors in the UI have been uniformly desaturated. These colors will be applied to different scenes, which may be backgrounds, action points, labels, or icons, etc., when color is used for the background, in order to ensure the text and background The color has enough contrast, and the light background with low saturation needs to be used together with the dark characters.

image

2.2.2 Design of illustration system

Turning on Dark Theme is like pulling the curtains of the room on and turning on a light. The surface of objects of different levels will be exposed to different light and show different colors of light and dark. The objects and characters in our illustration system follow this design. In a dark environment, due to insufficient light, the skin color of the character will darken and the color of the clothes will also change subtly. For example, white and bright clothes, in a dark environment, will appear gray and low saturation of dark colors.

image

3. Implementation Plan

Trip.com App uses a mixed development model of native system and React Native. On the basis of each system solution, combined with Trip.com's own characteristics, we have developed a set of Dark Theme adaptation solutions for iOS, Android and React Native.

3.1 iOS

We provide two themes for iOS 13 and above:

  • Adaptive mode: follow the system to show the Light / Dark theme

  • Forced Light Mode: App keeps the Light theme and does not change with the system theme

3.1.1 Principle of adaptation

The iOS system provides overrideUserInterfaceStyle property for UIWindow, UIViewController, UIView to control the Light / Dark theme, so as long as we control this property of KeyWindow, we can control the theme of the entire App.

3.1.2 Adaptation scheme

1) Set the switch

image

The logic of App theme setting is shown in the figure. KeyWindow only starts the Dark theme when both the App and the system enable Dark Theme.

Switching themes with the system needs to consider the situation when the system theme is switched when the App is running:

  • Go to the system settings page to switch manually

  • After turning on automatic switching, the system will automatically update the theme

In both cases, the App needs to enter the background, so you only need to add the App to enter the foreground to monitor, repeat the logic of 1 to complete the function of following the system to change the theme.

2) Color adaptation

The system provides the colorWithDynamicProvider method to adapt the color in Light / Dark mode. We package the color according to the visual color mapping scheme and cover most scenes. Some scenes that cannot be adapted by dynamic colors, such as CGColor and RGB colors, can be resolved by the resolvedColorWithTraitCollection method to use the color required by the current context.

3) Picture adaptation

As early as iOS12, the system added the userInterface property to UITraitCollection. We only need to register images of the two themes under Light / Dark to ImageAssets, and then UIImageView automatically obtains Light / Dark images according to the change of traitCollectionDidChange.

The static picture resources in the App can be directly configured through Images.xcassets, and the pictures delivered through the network or dynamically generated by the code can be dynamically registered through registerImage: withTraitCollection:

4) Matters needing attention

The principle of dynamic color or ImageAssets is to obtain the corresponding content according to the userInterface of the container. The dynamic color or ImageAssets on the view will be based on the userInterface of the view. The color calculation or image processing in the App will be based on UITraitCollection.currentColletion. value.

Set the theme of Window to complete the work of App theme adaptation. There will be cases where the App theme and the system theme are not synchronized. For example, the system theme is Dark and the App theme is Light. At this time, directly operating on dynamic colors or ImageAssets will get wrong results. Therefore, for such scenes, neither dynamic colors nor ImageAssets are used, and the view refresh operation is only performed when the theme switching occurs.

3.2 Android

We not only implemented Dark Theme on Android Q, but also adapted Dark Theme in versions below Android Q. On Android Q, users can choose to follow the system to display the Dark Theme or force the Dark to keep the Light theme closed.

Under Android Q, we also support Dark Theme, users can choose to force open or force close Dark Theme.

3.2.1 Principle of adaptation

When the Android App starts, it will load different resources according to the configuration of the system. Taking the loading picture as an example, the high-resolution system loads the triple image, and the low-resolution system loads the double image. Similarly, the system will load Dark or Light resources according to the opening or closing of Dark Theme.

We will place two sets of resources, Light and Dark, provided by UED under the value and value-night file directories of the App. When the App opens the Dark Theme, the system chooses to load resources from the value-night directory to display the Dark interface; when the App closes the Dark Theme, the system chooses to load resources from the value directory to display the Light interface.

3.2.2 Adaptation scheme

We introduce Android's Dark Theme adaptation solution through four sections: switch settings, color adaptation, picture adaptation and other considerations.

1) Switch setting

It can be seen from the above code that only the code that uses AppCompat has the Dark Theme feature. For example, inheriting AppCompatAcivity and AppCompatDialog only supports Dark Theme, while ordinary Activities and Dialog will not display Dark Theme, and Application also does not support it.

// 打开darkmode 

2) Color adaptation

Under the value and value-night directories, define the colors of Light and Dark with the same name, as shown below:

image

Use in XML or code

//xml 

Note: Activity must be an AppCompatActivity instance, not ApplicationContext / Activity. In addition, since the colors with transparency must be declared one by one in XML, in order to reduce the development workload, we provide a script that can quickly generate transparency colors under Light and Dark.

3) Picture adaptation

Picture adaptation work is divided into resource picture adaptation and custom drawable adaptation:

  • drawable / mipmap: Place the pictures with the same name as Light and Dark in the drawable-xxhdpi and drawable-night-xxhdpi directories. The system loads the pictures according to Light / Dark.

  • IconFont / Custom Shape / Custom Selector / SVG: Because drawing uses color, the usage is the same as color.

4) Matters needing attention

  • Display Dark Theme in non-AppCompatActivity, use the following code to display Dark color in non-AppCompatActivity.
public class IBUDarkModeDelegate {
  • The color name must be unique throughout the App.

  • Switching the Dark Theme of the mobile phone system will cause the Activity to rebuild, and the line of business will save and restore the state as needed.

  • Do a full model test to prevent abnormal display problems of individual models.

3.3 ReactNative

3.3.1 Adaptation scheme

The RN bridges the Native side, and obtains the theme changes of the Native side through two methods: direct acquisition and dynamic monitoring.

1) Get the current theme value from the Native side

Use the synchronization method of Native Modules to get the current theme value on the JS side. The method call on the JS side can directly get the return value of the Native synchronization method instead of a Promise.

The synchronization method was introduced into the Android and iOS sides of ReactNative in January and October 2017, but until now, it has not been written into the document:

  • iOS: Replace RCTEXPORTMETHOD () with RCTEXPORTSYNCHRONOUSTYPEDMETHOD () ( Commit supported in v0.51.0 and above )

  • Android: Add (isBlockingSynchronousMethod = true) after @ReactMethod annotation (v0.42.0 and above support Commit )

The disadvantage of the synchronization method is that it cannot be called when Debug Remotely, so you must provide the default value when Debug Remotely. When we connected the dark theme, we chose dark as the default.

2) Monitor the change of theme value

We use RN events to monitor Theme changes.

3) RN business party calls theme

We provide IBUThemeContext & IBUThemeProvider two categories for the production line to obtain the theme. Context provides a method for data transfer between component trees without manually adding props for each layer of components. IBUThemeContext is an application of Context on Theme. IBUThemeProvider is responsible for synchronizing the Theme value and passing it to IBUThemeContext.Provider.

// IBUThemeContext

By embedding IBUThemeProvider in the root node of the App, the component tree can obtain the theme value through the following two methods:

Read the global theme through IBUThemeProvider.theme. Use this.context in a class that declares static contextType = IBUThemeContext to get the theme value.

4) Color adaptation

We provide the following methods for the production line to use colors, and the methods support the setting of transparency:

export declare class IBUColor{

All methods accept two optional parameters, theme and alpha, the method will first select the hex string color value of the corresponding color according to the theme, if the theme value is empty, then fallback to IBUThemeProvider.theme, and then calculate the color of the color according to the alpha value The alpha hex value is concatenated to the hex string color value. If alpha is empty, hex color values ​​are not spliced. Finally, the corresponding hex color value string is returned.

5) Picture adaptation

We use lazy getters to solve the problem of Light / Dark picture display. The way is as follows:

The pictures on the RN side have been unified static resource management before:

export const images = {

Using lazy getters, after a little modification, it can be perfectly adapted:

export const images = {

6)DynamicStyle

The StyleSheet exported by ReactNative will only be initialized once when the file is imported, and will not change with the change of App DarkTheme. This leads to the problem that the RN cannot update the styles when the system theme changes, causing the RN page to be inconsistent with Native. To this end, we propose DynamicStyleSheet to solve this problem.

type IBUNamedStyles<T> = { [P in keyof T]: ViewStyle | TextStyle | ImageStyle };

IBUDynamicStyleSheet is a Function, which accepts a Function whose return value is style as a parameter, and returns a Function. This function is also called High Order Function .

StyleSheet's code for creating style is wrapped in the parameter's Function, which ensures that every time the value is taken, it will get the style corresponding to the current theme. Before each render, execute the returned Function once, and use the returned value of this Function as the real style.

IBUDynamicStyleSheet internally caches the styles under light and dark, so in most cases style will still be created only once, style will be created twice when the theme changes, and style will only be created at most twice when the theme changes many times .

Using DynamicStyleSheet this way, the code changes are not only small, but also the performance loss is small, to achieve the purpose of real-time switching Theme.

7)Examples

App open dark theme

export default class App extends Component{

Class Component access

class MyClass extends React.Component {

Functional Component access

export const MyComponent = () => {

Note: Component must declare contextType, otherwise it cannot trigger render redraw when the theme changes.

4. Tools & Efficiency

In the process of establishing the color specification to the implementation of the plan, we found that although the new color naming is easy to understand, due to the naming of the name used, the developer needs to check the corresponding color naming against the visual draft when using it, resulting in a waste of development efficiency.

For example, # 287DFA is displayed on the visual draft, and the mapping name brandingBlue of this color is searched according to the color value, and the color is set to brandingBlue.

In order to solve this problem, we extended the Sketch Measure plug-in, the color column no longer shows the color value of the color, and the name of the color is replaced. In this way, the color name can be obtained directly according to the visual draft, which greatly reduces the workload.

The plug-in effect is as follows:

image

So far, it perfectly solves the efficiency problem of developing and adapting Dark Theme.

V. Conclusion

Dark Theme adaptation is a project involving multi-functional departments. With the support of standardized design guidance, perfect landing solutions and convenient efficiency tools, our adaptation costs and resources have been greatly reduced. In the case of only one R & D staff at each end, it completed from plan formulation to plan implementation in two weeks, and promoted the production line access.

Trip.com has always been committed to following cutting-edge new features, bringing users the best experience, making users more comfortable, and traveling from now on.

image

Service recommendation

Published 0 original articles · liked 0 · visits 339

Guess you like

Origin blog.csdn.net/weixin_47143210/article/details/105658941