AndroidUtilCode AdaptScreenUtils screen adaptation notes and simple analysis

Headline Adaptation Principle
Android Screen Adaptation Terminator
A crude and fast Android full-screen adaptation solution

Briefly on the principle of screen adaptation
  • Introduction to size units
  1. dpi: Screen density, the number of pixels per inch on the screen. The total number of pixels on the diagonal of the screen is divided by the length of the diagonal of the screen.
  2. dip: It is the most commonly used dpunit. There are 160 dots per inch on the screen. If each dot represents 1 pixel, then 1dp is equal to 1 pixel.- The
    problem is, if there are 320 pixels per inch on the screen, the screen width is 1080 pixels, how much dp is the screen width at this time?
    1. The screen is 320 pixels per inch. If 160 points are used to cover these pixels, each point can represent 2 pixels, that is, 2 pixels represent 1dp, and the screen is at this time With 1080 pixels, it needs to be covered with 540 points, and the screen size is 540dp.
  3. density: Divide 160 points per 1 inch of pixels, that is, there are 160 points per inch, how many pixels can each point cover.
  • Explain the principle
  1. The UI image size and pixels are fixed.
  2. If the design width is 360dp and the screen pixels of different devices are different, if the pixel value calculated by multiplying 360dp by the density is equal to the width of each device's screen pixel, then you can change the density in the current Activity to achieve the goal.
See AdaptScreenUtilshow it fits
  1. It is very simple to use, just rewrite Activitythe getResources()method as follows:
@Override
public Resources getResources() {
    
    
    // 这里是以高度为基准来适配的
    return AdaptScreenUtils.adaptHeight(super.getResources(), "UI高度像素值");
}
  1. Look at the source code
public final class AdaptScreenUtils {
    
    
    public static Resources adaptHeight(final Resources resources, final int designHeight) {
    
    
        // designHeight代表UI设计稿中的高度像素值
        return adaptHeight(resources, designHeight, false);
    }
    public static Resources adaptHeight(final Resources resources, final int designHeight, final boolean includeNavBar) {
    
    
        // 获取屏幕高度像素值
        float screenHeight = (resources.getDisplayMetrics().heightPixels  + (includeNavBar ? getNavBarHeight(resources) : 0)) * 72f;
        // 以屏幕高度像素值除以设计稿中高度像素值,传入applyDisplayMetrics()方法中
        float newXdpi = screenHeight / designHeight;
        applyDisplayMetrics(resources, newXdpi);
        return resources;
    }
    private static void applyDisplayMetrics(final Resources resources, final float newXdpi) {
    
    
        // 将上面得到值赋值给DisplayMetrics中的xdpi变量
        resources.getDisplayMetrics().xdpi = newXdpi;
        Utils.getApp().getResources().getDisplayMetrics().xdpi = newXdpi;
        applyOtherDisplayMetrics(resources, newXdpi);
    }
    // 该方法是通过反射为将resources对象中的xdpi变量改为newXdpi值.
    private static void applyOtherDisplayMetrics(final Resources resources, final float newXdpi) {
    
    
        if (sMetricsFields == null) {
    
    
            sMetricsFields = new ArrayList<>();
            Class resCls = resources.getClass();
            Field[] declaredFields = resCls.getDeclaredFields();
            while (declaredFields != null && declaredFields.length > 0) {
    
    
                for (Field field : declaredFields) {
    
    
                    if (field.getType().isAssignableFrom(DisplayMetrics.class)) {
    
    
                        field.setAccessible(true);
                        DisplayMetrics tmpDm = getMetricsFromField(resources, field);
                        if (tmpDm != null) {
    
    
                            sMetricsFields.add(field);
                            tmpDm.xdpi = newXdpi;
                        }
                    }
                }
                // 包括resources父类对象中的xdpi值都要改为newXdpi值
                resCls = resCls.getSuperclass();
                if (resCls != null) {
    
    
                    declaredFields = resCls.getDeclaredFields();
                } else {
    
    
                    break;
                }
            }
        } else {
    
    
            applyMetricsFields(resources, newXdpi);
        }
    }
}

xDpiWhere is it used?

public class TypedValue {
    
    
    public static float applyDimension(int unit, float value,DisplayMetrics metrics){
    
    
        switch (unit) {
    
    
        case COMPLEX_UNIT_PX:
            return value;
        case COMPLEX_UNIT_DIP:
            return value * metrics.density;
        case COMPLEX_UNIT_SP:
            return value * metrics.scaledDensity;
        case COMPLEX_UNIT_PT:
            // 假如使用的是pt作为单位,xdpi为屏幕像素比设计稿像素,再乘以当前value值,最终的结果就是value值在屏幕中所占像素值.后面的我不太懂0.0.
            // 使用pt作为单位可以避开dp单位,这样对原有的项目影响最小.
            return value * metrics.xdpi * (1.0f/72);
        case COMPLEX_UNIT_IN:
            return value * metrics.xdpi;
        case COMPLEX_UNIT_MM:
            return value * metrics.xdpi * (1.0f/25.4f);
        }
        return 0;
    }
}
note

For the TextViewsize of Chinese text, it is recommended to use it spas a unit, so that the text size can be automatically adapted. Then, do not write down the TextViewsize, or it is easy to TextViewcause the text to be larger than the size and cause incomplete display. It is recommended wrap_content.

Guess you like

Origin blog.csdn.net/MoLiao2046/article/details/107307544