preface

When it comes to Android screen adaptation, it is a commonplace topic, and the purpose of adaptation is nothing more than the UI performance of different devices should be proportional to the design drawing. In the actual adaptation process, in the face of different models, a variety of resolutions, have you adapted correctly? Do you apply OOM because the picture is not in the right position? This article introduces the width and height qualifiers and SW qualifiers of common screen adaptation schemes, with emphasis on SW qualifiers and image adaptation.

1. Screen adaptation solution

1. Width and height qualifier (resolution qualifier)

Take all the phone widths and heights in the market, generate res files such as values-1920 × 1080, Values-1280 × 720,values-1024 × 600, etc., write DIMens files using one of the resolutions (same as UI design) as a benchmark. Then, all other resolutions are calculated according to the benchmark resolution to generate dimens files with corresponding resolutions. When using, the corresponding DIMens values are directly used in XML according to the UI design drawing. Values under the corresponding DIMens will be used for different resolutions.

There are two big problems with this plan:

  • Problem 1: Generating dimens files is troublesome, but it can be generated using tools, so it can be solved.
  • For example, values-1920 × 1080 is configured. If the resolution of a weird phone is 1920 × 1070, the default DIMens will be used because there is no corresponding qualifier, and then the UI will be deformed. You need to generate dimens files for this weird resolution.

2. Sw qualifier

Also known as the minimum width qualifier, Android identifies the minimum dp of the available height and width of the screen (typically the dp of the phone width), then uses the corresponding resource file in the resource file based on the identified result, and if it does not find a corresponding resource file, it searches down, and finally uses the default. For example, if sw= 360DP, values-SW360DP will be preferred. If there is no values-360DP and only Values350DP, values350DP will be used. If there is no one smaller than 350DP and values350DP, the default configuration will be used (under values). This scheme is widely used because it is easier to hit a resource than the width and height qualifier, and even if there is no resource, close ones will be used. The UI effect is not much different, so this scheme is widely used.

2. Screen adaptation Directory meaning

By default, portrait screen will be introduced, if there is a difference between vertical screen adaptation will be specially explained

1. Layout fit (Layout directory)

Layout adaptation loads a specified layout based on one of the adaptation schemes

Layout Default directory layout-land Landscape layout-port Portrait Normally, the default directory is portrait. Add layout-land for landscape and vice versa

1.1 Width and height qualifiers

Before android3.0, name the layout folder as follows: layout-1024 × 768 layout-1024 × 600 layout-1280 × 768

After android3.0, subtract 48 pixels from the height of the bottom status bar: layout-976 × 768 layout-976 × 600 layout-1232 × 768

To distinguish between vertical and horizontal adaptation (android3.0 or later), add land or port to the directory name. Layout -land-1024 x 720 for vertical adaptation: layout-port-976 x 768 for vertical adaptation

1.2 SW qualifier

The name is layout-SW360DP layout-SW392DP layout-SW411DP

To differentiate between vertical and horizontal adaptation, add land or port to the directory name.

layout-sw360dp-land layout-sw360dp-port

1.3 W or H qualifier

In addition, there is a directory layout- w360DP, and layout- SW360DP difference, for example

1.3.1. The layout – sw360dp

When the absolute width of your screen is greater than 360DP, the screen will automatically call the layout in the folder layout-sw360DP.

Note: The absolute width here refers to the actual width of the phone, regardless of the horizontal or vertical screen. Sw minimum width refers to the small value of screen width and height. Each screen is fixed and does not change as the screen changes horizontally and vertically.

1.3.2. The layout – w360dp

When the relative width of your screen is greater than 360DP, the screen automatically calls the layout in the layout-w360DP folder.

Note: The relative width here refers to the relative width of the phone; That is, when the phone is portrait, the length of the smaller side; When the phone is landscape, it is the length of the longer side. When the screen is switched horizontally and vertically, the width of the screen is changed. Compare the changed width with the original width to see whether to use the resources under the resource file.

1.3.3. Layout – h360dp

The use of layout-W360DP is the same, but here refers to the relative height. This method is rarely used, however, because the screen can generally scroll vertically, resulting in varying lengths, rather than being as fixed as widths. Because this method is not very flexible, the Official Google documentation recommends using this method as little as possible.

Here, the DPI values of SW, W and H are calculated as follows

DisplayMetrics metrics = getResources().getDisplayMetrics();
int widthDpi = (int) (metrics.widthPixels / metrics.density); 
int heightDpi = (int) (metrics.heightPixels / metrics.density);
Copy the code

Sw: Set widthDpi and heightDpi to smaller values w: widthDpi h: heightDpi

2. Dimen Adaptation (VALUES directory)

Values directory can put more resources, such as dimen, color,style, internationalization language. The values directory structure can be as complex as values-port-xhpdi-1280 × 768-4

The layout qualifier is described above. Normally, the length qualifier is used for multiple points, and the process is the same as above.

3. Sw Dimen adaptation process

Select one of the devices as the base fit, and then use the base device to generate the SW values of the other devices in proportion

Refer to the calculation formula:

px = density * dp;

density = dpi / 160;

px = dp * (dpi / 160);
Copy the code

The calculation formula of SW-XXXX-DP is as follows:

sw *160/dpi
Copy the code

Sw is the smaller side of the width and height

3.1. Dimen adaptation

  1. If the resolution of the benchmark device is 1080 × 1920, DPI =360, density=3 and picture directory xxhdPI are selected, thenvalues-sw360dp.1dp=1dp
  2. It needs to be adapted to other devices (device 1 and 2), and the equal ratio treatment is as follows:
  • Device 1: resolution 1080 × 1920, DPI =420, density= 2.625,values-sw411dp.1 dp = 411/360 * 1 dp = 1.14 dp
  • Device 2: resolution 1080 × 1920, DPI =360, density=2.25,values-sw480dp.1 dp = 480/360 * 1 dp = 1.33 dp
  • Device 3: resolution 720 × 1280, DPI =240, density=1.5,values-sw480dp.1 dp = 480/360 * 1 dp = 1.33 dp
  • Device 4: resolution 480 × 840, DPI =240, density=1.5,values-sw320dp.1 dp = 320/360 * 1 dp = 0.88 dp
  • Device 5: resolution 480 × 840, DPI =160, density=1,values-sw480dp.1 dp = 480/360 * 1 dp = 1.33 dp

Note: Device parameters source simulator 3.

| | values directory dp value | — — — — — — — – | — — — — — — — — — — — — – | — — — — — — — — — — — — – | values (default directory and benchmark) 1 dp = 1 dp | | values – sw320dp dp | | 1 dp = 0.88 Benchmark values – sw360dp (sw) | 1 dp = 1 dp | values – sw411dp dp | | 1 dp = 1.14 values – sw480dp | 1 dp = 1.33 dp

  1. Then adjust the blue Lake resolution design width ** 360DP **

5. Select dp according to the number of DP marked in the design control.

6. Test verification: When you label the control as 250dp× 250DP, the width ratio is similar across different devices

  • On the base device SW360DP, 250DP -> 250DP x 1DP = 250DP
  • On the device SW320DP, 250DP -> 250DP × 0.88DP = 220DP
  • On the SW411DP device, 250DP -> 250DP x 1.14DP = 285DP
  • On sw480DP, 250DP -> 250DP x 1.33 DP =332.5 DP

The dp value of the device will eventually be converted to px value (according to the formulapx= dp * density), so the final value of 250DP for the above reference device and the 5 devices is

  • Values -SW360DP (density=3), 250DP * 3=750px, and width ratio: 750/1080=0.6944
  • Device 1: Resolution 1080 × 1920, DPI =420, density= 2.625,values -SW411DP, 285DP * 2.625= 748.12px, and width ratio: 748.125/1080=0.6927
  • Density =2.25 values sw480DP, 332.5DP *2.25= 748.12px, and width ratio: 748.125/1080=0.6927
  • Dpi =240, density=1.5,values- SW480dp, 332.5dp*1.5=498.75px, and width ratio: 498.75px/720=0.6927
  • Dpi =240, density=1.5,values- SW320DP, 220DP *1.5=330px, and width ratio: 330px/480=0.6875
  • Dpi =160, density=1,values sw480DP, 332.5dp*1=332.5px, and width ratio: 332.5px/480=0.6927

It can be found from the above that the final ratio is about 0.6927, so the screen adaptation has completed equal scale scaling, and the error range is acceptable. If there is a big difference, it indicates that there is a problem with your adaptation. The difference between 0.6927 and 0.6875 above is because the decimal part is omitted when calculating SWDP. For example, device 1 was originally 411.4285714285714, and the value is 411DP. The values-SWDP whose value is less than or equal to 411.4285714285714 dp is matched by the system. The values-SWDP whose value is greater than 411.4285714285714 DP is not matched.

Add Sw code calculation method: Sw calculation method 1:

/** * get SmallestWidthDP *@param context
	 * @return* /
	public static float getSmallestWidthDP(Context context) {
	    DisplayMetrics dm = context.getResources().getDisplayMetrics();
	    int heightPixels =getScreenHeight(context);
	    int widthPixels = getScreenWidth(context);
	    float density = dm.density;
	    float heightDP = heightPixels / density;
	    float widthDP = widthPixels / density;
	    float smallestWidthDP;
	    if (widthDP < heightDP) {
	        smallestWidthDP = widthDP;
	    } else {
	        smallestWidthDP = heightDP;
	    }
	    return smallestWidthDP;
	}
	/** * get the screen width **@param context Context
	 * @returnScreen width (px) */
	public static int getScreenWidth(Context context) {
	    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
	    Point point = new Point();
	    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
	        wm.getDefaultDisplay().getRealSize(point);
	    } else {
	        wm.getDefaultDisplay().getSize(point);
	    }
	    return point.x;
	}
	
	/** * Get the screen height **@param context Context
	 * @returnScreen height (px) */
	public static int getScreenHeight(Context context) {
	    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
	    Point point = new Point();
	    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
	        wm.getDefaultDisplay().getRealSize(point);
	    } else {
	        wm.getDefaultDisplay().getSize(point);
	    }
	    return point.y;
	}
Copy the code

Sw Calculation Method 2:

int  smallestWidthDP2 = (Math.min(heightPixels,widthPixels)) * 160 / dm.densityDpi;
Copy the code

Sw Calculation Method 3:

int smallestScreenWidthDp3 =context.getResources().getConfiguration().smallestScreenWidthDp;
Copy the code

Generate values-sw directories in batches

How to calculate the sw value is described above. In practice, there are two ways to generate the length of different SW values:

  1. Use ScreenMatch to batch generate values-sw directories
  2. Use the following utility classes:
package com.sjl.lib.screenadaptation;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** * sw Generate tool class **@author Kelly
 * @version 1.0.0
 * @filename MakeDpXml
 * @timeBehold, 2020/11/30 *@copyright(C) 2020 song
 */
public class MakeDpXml {
    /** * base value in dp */
    private static int baseSw = 1080;
    private static List<Integer> sw = Arrays.asList(360.392.411.1080.1440.2160);
    private static int decimals = 4;
    private static int scale = 1;
    private static String filename = "dimens.xml";

    public static void main(String[] args) {
        // Customize parameters
        baseSw = 1080;
        decimals = 4;
        scale = 1;
        // Template file, file storage F:/layout, you can also define your own
        filename = "dimens.xml";
        create();
        System.out.println("At the end of MakeDp");
    }

    public static void create(a) {
        // The contents of dimens. XML file in this folder are the initial reference values
        File file = new File("F:/layout",filename);
        List<String> lines = new ArrayList<>();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString;
            while((tempString = reader.readLine()) ! =null) { lines.add(tempString); }}catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(reader ! =null) {
                try {
                    reader.close();
                } catch (Exception ex) {

                }
            }
        }
        int lineSize = lines.size();
        if (lineSize == 0) {
            return;
        }

        Map<Integer, String> resultContent = new HashMap<>();
        for (int j = 0; j < sw.size(); j++) {
            Integer tempSw = sw.get(j);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < lineSize; i++) {
                String xmlStrLine = lines.get(i);
                if (xmlStrLine.contains("</dimen>")) {
                    String start = xmlStrLine.substring(0, xmlStrLine.indexOf(">") + 1);
                    String end = xmlStrLine.substring(xmlStrLine.lastIndexOf("<") - 2);
                         
                    String text = xmlStrLine.substring(xmlStrLine.indexOf(">") + 1,
                            xmlStrLine.indexOf("</dimen>") - 2);
                    if (text.startsWith("@dimen")) {
                        sb.append(xmlStrLine).append("\r\n");
                        continue;
                    }
                    Float num = Float.parseFloat(text);
                    // Compute new values, concatenate new strings, and wrap new lines at the end according to different sizes.
                    float value = (float) tempSw / baseSw * num;
                    if(tempSw ! = baseSw){ value = value / scale; } sb.append(start).append(String.format("%."+decimals+"f", value)).append(end).append("\r\n");
                } else {
                    sb.append(xmlStrLine).append("\r\n");
                }
            }
            resultContent.put(tempSw, sb.toString());
        }

        // Write to the file
        for (int i = 0; i < sw.size(); i++) {
            Integer tempSw = sw.get(i);
            String s = resultContent.get(tempSw);
            File dir = new File("F:/layout/values-sw" + tempSw + "dp",filename);
            if(! dir.getParentFile().exists()) { dir.getParentFile().mkdirs(); } MakeXmlUtils.writeFile(dir.getAbsolutePath(), s); }}}Copy the code

MakeXmlUtils:

/** * write file */

    public static void writeFile(String file, String text) {
        PrintWriter out = null;
        try {
            out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            out.println(text);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(out ! =null) { out.close(); }}}Copy the code

3.2. Picture adaptation

If the control is a picture and the width and height of the control are specified according to the design drawing, how to choose which density of the picture?

Operation steps:

  1. Calculate device density DPI
DisplayMetrics   dm = getResources().getDisplayMetrics();
int densityDpi = dm.densityDpi;
Copy the code
  1. Then refer to the figure below
directory The density of the corresponding Device density Recommended size of LOGO Density range
ldpi 120dpi 0.75 36 * 36 0-120.
mdpi 160dpi 1 48 * 48 120dpi~160dpi
hdpi 240dpi 1.5 72 * 72 160-240.
xhdpi 320dpi 2 96 * 96 240-320.
xxhdpi 480dpi 3 144 * 144 320-480.
xxxhdpi 640dpi 4 192 * 192 480-640.
  1. According to the actual DPI of the device to choose pictures to download and store, generally choose a baseline density, such as 360Dpi, such as XXHDPI, and then run on different devices, control display length finally calculated width accounted for the same, the above has been explained.

  2. However, when running to devices with different DPI, the memory occupied is not the same, has nothing to do with the control display size, do not attempt to modify the control display size to reduce the application memory. If and only when the device density range is 320DP to 480dpi, xxHDPI is the best match (the definition is the best, the memory occupation is appropriate). The memory of other device density images decreases or increases, and the images appear blurred to different degrees.

The diMEN adaption length is the same as the width ratio, but the memory occupied by the image is different. The memory occupied by the image is related to the image resolution, pixel storage format, the drawable folder where the image is located and the DEVICE DPI.

The memory footprint of pixels is affected by the storage mode of Bitmap colors:

  • ARGB_8888: A->8bit-> one byte, R->8bit-> one byte, G->8bit-> one byte, B->8bit-> one byte, i.e. 8888, A pixel total of four bytes, 8+8+8+8=32bit=8byte
  • ARGB_4444: A->4bit-> half A byte, R->4bit-> half A byte, G->4bit-> half A byte, B->4bit-> half A byte, that is, 4444, A pixel total of two bytes, 4+4+4+4=16bit=2byte
  • RGB_565: R->5bit-> half a byte, G->6bit-> half a byte, B->5bit-> half a byte, i.e. 565, a pixel total of two bytes, 5+6+5=16bit=2byte ALPHA_8: R->5bit-> half a byte, G->6bit-> half a byte, B->5bit-> half a byte, i.e. A->8bit-> 1byte, i.e. 8, each pixel is A total of one byte, 8=8bit=1byte

Before giving examples, know the formula for calculating the actual width and height of an image

Width of the new figure = width of the original figure * (DPI of the device/dPI of the directory) Height of the new figure = Height of the original figure * (DPI of the device/DPI of the directory)Copy the code

Android :layout_width android:layout_height Android :layout_height

Image memory size = Width x height * memory bytes per pixelCopy the code

The actual width and height of the image are not directly calculated, strictly speaking, the actual size of the image in the form of bitmap in memory. So the above

Memory occupied by an image = Bitmap width xbitmap height x Memory bytes occupied by a pixel Bitmap width = Width of the original image x (DPI of the device/directory) Bitmap height = height of the original image x (DPI of the device/directory Dpi)Copy the code

or

Image memory size = original image width * (inTargetDensity/inDensity) * Original image height * (inTargetDensity/inDensity) * Number of bytes occupied by each pixelCopy the code

InDensity: indicates the DPI of the target image (under which resource folder), i.e., the dPI of the directory inTargetDensity: So you can see that inDensity and inTargetDensity stretch the width and height of the Bitmap to change how much memory the Bitmap occupies

For example:

Suppose the dPI of your device is 360DP, the density is 3, the corresponding image directory is XXhdPI, the resolution is 1080 × 1920, the SW is SW360, there is a picture with the width and height of 250px ×250px, suppose you put the wrong picture directory (not MDPI, normally put in xxhdPI directory), Images take up different amounts of memory.

  1. The picture in the wrong directory leads to the picture width and height change, which leads to the picture memory change analysis. Now let’s calculate the memory changes of images in different directories
Storage directory Width calculation Memory changes
ldpi 360/120 * 250 bigger
mdpi 360/160 * 250 bigger
xxdpi 360/360 * 250 normal
xxdpi 360/640 * 250 smaller

The same goes for height. As can be seen from the above,** The same picture on the same device occupies different memory in different picture directories **.

  1. Assuming your image is properly placed in xxHDPI, the memory changes when you run it on a different DPI device:

Calculation reference:

Width of new image = width of original image * (DPI of device/DPI of directory)Copy the code
  • Device 1: Resolution 1080 × 1920, DPI =420, density= 2.625, VALUES – SW411DP, 420/360*250, increased
  • Device 2: Resolution 1080 × 1920, DPI =360, DENSITY =2.25, VALUES – SW480DP, 360/360*250, normal
  • Device 3: Resolution 720 × 1280, DPI =240, density=1.5, VALUES – SW480DP, 240/360*250, smaller
  • Device 4: Resolution 480 × 840, DPI =240, density=1.5, VALUES -SW320DP, 240/360*250, smaller
  • Device 5: Resolution 480 × 840, DPI =160, density=1, VALUES sw480DP, 160/360*250, smaller

As can be seen from the above, ** The same picture on different devices is in the same directory, and the dPI of different devices occupies different memory **.

In short, usually we are a set of image adaptation, but if a set of image adaptation, there are slight differences, need to be adapted separately for different devices DPI. Note that the image directory storage location should not be too different, otherwise it is prone to OOM, blurred pictures and other problems.

4. Example of sw adaptation benchmark device

The following data is the SW value of each device. You can select one device as the reference value for adaptation, and then use the reference device to generate the SW value of other devices. The adaptation process is the same as the preceding SW DImen adaptation process terminal device example:

size The screen The resolution of the The density of Relationship between dp and PX sw Blue Lake preview resolution custom
8 Vertical screen 800 × 1280 1 mdpi 1:1 sw800
10.1 landscape 1280 × 800 1 mdpi 1:1 sw800
55 Vertical screen 1080 × 1920 1 mdpi 1:1 sw1080
21 Vertical screen 1080 x 1920 1 mdpi 1:1 sw1080
17 landscape 1280 × 1024 1 mdpi 1:1 sw1024

Mobile phone:

size The screen The resolution of the The density of Relationship between dp and PX sw Blue Lake preview resolution custom describe
5.2 Vertical screen 800 × 1280 3 xxhdpi 1:3 sw360 360 * 640
6.4 Vertical screen 2340 × 1080 3 xxhdpi 1:3 sw360 360 * 780

Screen direction judgment:

If (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
    / / vertical screen
    System.out.println("Portrait");
} else {
    / / landscape
    System.out.println("Landscape");
}
Copy the code

5. Get dimen from code

There are three main ways to reference dimen. XML dp values in Java or Kotlin code:

  1. getDimensionReturns a float value
  2. getDimensionPixelOffsetStrongly converting float to an int is returned
  3. getDimensionPixelSizeReturns a float value rounded to an int value

The value returned by the above three methods is based on the length unit of the SW XML file:

  1. When the given value is px, the given value is returned directly
  2. When the given value is dp, multiply the screen density and return
  3. When the given value is sp, the scaling factor is multiplied and returned

If you use the dp value as a font size, you need to pay attention to magnification.

XML set font 20dp

 <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="@dimen/dp_20"
        />
Copy the code

Set 20DP in Java code

		float size = context.getResources().getDimension(R.dimen.dp_20);
		TextView textView = new TextView(context);
		textView.setTextSize(size);
Copy the code

The font result value above will be larger than the XML value (device density is not 160dpi, i.e. 1px does not equal 1DP), resulting in an unsatisfactory display. The reason is that as stated above, when the given value is dp, the screen density is multiplied and returned

To be compatible with other devices, the correct dp value is as follows:

       float size = context.getResources().getDimension(R.dimen.dp_20)/ context.getResources().getDisplayMetrics().density;
		TextView textView = new TextView(context);
		textView.setTextSize(size);
Copy the code

This setting is the correct value, display as expected.

6. Expansion (Toutiao adaptation)

Toutiao adaptation scheme achieves adaptation purpose by modifying system density. In Android, no matter what unit is used, the system will eventually convert the size to PX, and

px = dp * density
Copy the code

The density used by the system is a member variable in DisplayMetrics, and the DisplayMetrics instance is available via Resources#getDisplayMetrics, Resouces are obtained from the Activity or Application Context. In other words, all dp and PX conversions are calculated by the relevant values in DisplayMetrics. Therefore, dp adaptation can be completed only by modifying the density value in DisplayMetrics. Sp ADAPTS similarly, but with a scaling factor that allows users to change font sizes

public class ScreenAdpt {
    /** the width of the design is dp */
    private static final float width = 360;


    private static float textDensity = 0;
    private static float textScaledDensity = 0;


  

    / * * *@param activity
     */
    public static void setCustomDensity(@NonNull final Activity activity) {
        final Application application = activity.getApplication();
        final DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
        if (textDensity == 0) {
            textDensity = displayMetrics.density;
            textScaledDensity = displayMetrics.scaledDensity;
            application.registerComponentCallbacks(new ComponentCallbacks() {
                @Override
                public void onConfigurationChanged(Configuration configuration) {
                    if(configuration ! =null && configuration.fontScale > 0) { textScaledDensity = application.getResources().getDisplayMetrics().scaledDensity; }}@Override
                public void onLowMemory(a) {}}); }final float targetDensity = displayMetrics.widthPixels / width;
        
        final float targetScaledDensity = targetDensity * (textScaledDensity / textDensity);
        final int targetDpi = (int) (160 * targetDensity);

        displayMetrics.density = targetDensity;
        displayMetrics.scaledDensity = targetScaledDensity;
        displayMetrics.densityDpi = targetDpi;

        finalDisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics(); activityDisplayMetrics.density = targetDensity; activityDisplayMetrics.scaledDensity = targetScaledDensity; activityDisplayMetrics.densityDpi = targetDpi; }}Copy the code

7. Summary

In summary, the smallestWidth qualifier screen ADAPTS scenarios in which the ratio of View to screen width on different devices is the same as in the design drawing. The adaptation needs to be noted is to choose one of the devices as the reference, and then use the reference device (minimum width reference value) to generate the SW value of other devices in equal proportion, otherwise it is easy to cause problems, UI designers generally do not have this awareness, most of the map based on a certain resolution, when you choose the SW qualifier adaptation, Most need to customize the resolution preview (blue Lake, Mouk, etc.), otherwise it is easy to choose the wrong length and image size, leading to a series of problems. Please correct any mistakes above.