Andorid screen adaptation

Andorid screen adaptation

Link to this article: https://blog.csdn.net/feather_wch/article/details/131672378

Reference article: Summary of Android Adaptation

1. What is dpi?

  1. screen pixel density
  2. 160 pixels per inch, 160dpi
  3. dpi = px / in

2. dp and px conversion

  1. px = dp * (dpi / 160)
  2. density: dpi / 160

3. Adaptation strategy (width percentage, height aspect ratio)

  1. The width of the control is in accordance with the size of the UI design
  2. The height of the control is calculated according to the percentage of the proof

Toutiao Adaptation Solution

1. Let dp have a percentage effect

  1. px = dp * density
  2. Modify density (stored in DisplayMetrics)
  3. When the Activity starts, call the relevant adaptation method, and pass in the activity and application (to deal with the case that the DisplayMetrics of the two are different)
  4. very lightweight

2. What are the important properties and methods of DisplayMetrics?

  • widthPixels : The width of the display device, in pixels.
  • heightPixels : Displays the height of the device in pixels.
  • density : Displays the logical density of the device, which is the ratio of dots per inch (dpi) divided by 160.
  • densityDpi : Displays the physical density of the device in dots per inch (dpi).
  • scaledDensity : Displays the scaling density of the device, used for text scaling, usually the same as density, unless the user modifies the font size.

3. It is necessary to recalculate the density, so the proof is 360dp as the standard

  1. Calculate density, densityDpi, scaledDensity
  2. Assign DisplayMetrics set to Application and Activity
公式:px = dp * density, density = px / dp
新density = DisplayMetrics.widthPixels / 360
公式:density = dpi / 160,dpi = density * 160
新densityDpi = 160 * 新density

// 设置DisplayMetrics
displayDensity.density = 新density
displayDensity.densityDpi = 新densityDpi

4. There is a problem with font scaling, either too large or too small, how to deal with it? scaledDensity

  1. scaledDensity needs to scale the density density according to the same proportion
  2. When the system modifies the font size, the interface will be triggered, and the scaledDensity of the font needs to be recalculated after the interface is triggered

percentage scheme

5. How is the percentage scheme realized?

  1. Calculate and generate xml files, different xml files with different resolutions,
  2. dp, px use parameters such as x1, y1, etc., which will be converted internally

DisplayMetrics source code

1. When is DisplayMetrics set?

  • DisplayMetrics is set in the WindowManagerService class.
SystemServer.java】
private void startOtherServices() {
    
    
    final Context context = mSystemContext;
    WindowManagerService wm = null;
    InputManagerService inputManager = null;
    ...
    //创建WindowManagerService对象
    wm = WindowManagerService.main(context, inputManager,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                !mFirstBoot, mOnlyCore, new PhoneWindowManager());
    //添加到服务管理器
    ServiceManager.addService(Context.WINDOW_SERVICE, wm);
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
    ...
    //调用displayReady方法
    wm.displayReady();
    ...
}WMSpublic void displayReady() {
    
    
    synchronized (mWindowMap) {
    
    
        //初始化显示设备
        for (Display display : mDisplays) {
    
    
            DisplayContent displayContent = mRoot.getDisplayContentOrCreate(display.getDisplayId());
            //配置显示策略
            configureDisplayPolicyLocked(displayContent);
            //设置布局标志
            displayContent.layoutNeeded = true;
            //更新方向
            boolean configChanged = updateOrientationFromAppTokensLocked(false);
            //设置临时配置
            mTempConfiguration.setToDefaults();
            mTempConfiguration.fontScale = 1;
            //更新资源配置
            if (configChanged) {
    
    
                mWaitingForConfig = true;
                startFreezingDisplayLocked(false, 0, 0, displayContent);
                //发送配置变化广播
                sendNewConfiguration(display.getDisplayId());
            }
        }
        //初始化输入设备
        mInputMonitor.setUpdateInputWindowsNeededLw();
        performLayoutAndPlaceSurfacesLocked();
        mInputMonitor.updateInputWindowsLw(false /*force*/);
    }
}PhoneWindowManager- WindowManagerPolicy的实现类
private void configureDisplayPolicyLocked(DisplayContent displayContent) {
    
    
    //设置显示设备的初始尺寸和密度
    mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
            displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight,
            displayContent.mBaseDisplayDensity);
    //设置显示设备的overscan区域
    DisplayInfo displayInfo = displayContent.getDisplayInfo();
    mPolicy.setDisplayOverscan(displayContent.getDisplay(),
            displayInfo.overscanLeft, displayInfo.overscanTop,
            displayInfo.overscanRight, displayInfo.overscanBottom);
}PhoneWindowManager- WindowManagerPolicy的实现类
public void setInitialDisplaySize(Display display, int width, int height, int density) {
    
    
    if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
    
    
        synchronized (mLock) {
    
    
            //初始化真实屏幕大小
            mOverscanScreenWidth = mOverscanScreenHeight = 0;
            mUnrestrictedScreenWidth = width;
            mUnrestrictedScreenHeight = height;
            //初始化DisplayMetrics
            mDisplayWidth = width;
            mDisplayHeight = height;
            mDisplayDensity = density;
            mSystemGestures.screenWidth = width;
            mSystemGestures.screenHeight = height;
        }
        //更新显示区域
        updateOrientationListenerLp();
        updateRotation(true);
    }
}

Guess you like

Origin blog.csdn.net/feather_wch/article/details/131672378
Recommended