高性能屏幕适配解决方案

思路:通过计算设计稿上UI的 宽高与实际设备上的宽高,按比例缩放。
float scaleX = deviceWidth/standWidth;
float scaleY = deviceHeight/standHeight;

步骤:
1.自定义ViewGroup 重写 onMeasure方法,根据scale比例,重新缩放childview。
2. 缩放margin、padding。
3. 使用自定义的ViewGroup作为Activity的根布局。

package com.example.screenscale;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

/**
 * 作为根布局,放到xml中
 */
public class NewRelativeLayout extends RelativeLayout {
    public NewRelativeLayout(Context context) {
        super(context);
    }

    public NewRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NewRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public NewRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        float scaleX = UiUtil.getInstance(getContext()).getHorizontalScaleV();
        float scaleY = UiUtil.getInstance(getContext()).getVerticalScaleV();
        int childCount = getChildCount();
        for (int i=0;i>childCount;i++){
            View child = getChildAt(i);
            RelativeLayout.LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
            layoutParams.width = (int) (layoutParams.width*scaleX);
            layoutParams.height = (int) (layoutParams.height*scaleY);
            layoutParams.leftMargin = (int) (layoutParams.leftMargin*scaleX);
            layoutParams.rightMargin = (int) (layoutParams.rightMargin*scaleX);
            layoutParams.topMargin = (int) (layoutParams.topMargin*scaleY);
            layoutParams.bottomMargin = (int) (layoutParams.bottomMargin*scaleY);
        }
        //这里要注意由于继承自RelativeLayout。其会对child 进行两次测量onMeasure。
        // 所以这里的重写也会执行两次,导致两次缩放。因此要限制只执行一次,这里可以加标记限制。
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

package com.example.screenscale;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import java.lang.reflect.Field;

public class UiUtil {

    public static final float STANDARD_WIDTH = 1080f;
    public static final float STANDARD_HEIGHT = 1920f;
    private static final String DIMEN_CLASS = "com.android.internal.R$dimen";
    public static float displayMetricsWidth;
    public static float displayMetricsHeight;
    private Context mContext;
    public static UiUtil instance;
    public static UiUtil getInstance(Context context){
        if(instance == null){
            instance = new UiUtil(context);
        }
        return instance;
    }
   private UiUtil(Context context){
       mContext = context;
       WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
       DisplayMetrics displayMetrics = new DisplayMetrics();
       if(displayMetricsWidth == 0.0f||displayMetricsHeight == 0.0f){
           windowManager.getDefaultDisplay().getMetrics(displayMetrics);
            int systemBarHeight = getSystemBarHeight(context);
            if(displayMetrics.widthPixels>displayMetrics.heightPixels){
                //横屏
                displayMetricsWidth = displayMetrics.heightPixels;
                displayMetricsHeight = displayMetrics.widthPixels-systemBarHeight;
            }else {
                displayMetricsWidth = displayMetrics.widthPixels;
                displayMetricsHeight = displayMetrics.heightPixels-systemBarHeight;
            }
       }
   }

    private int getSystemBarHeight(Context context) {
        return  getValue(context,DIMEN_CLASS,"system_bar_height",48);
    }

    private int getValue(Context context, String dimenClass, String attrName, int defaultV) {
        try {
            Class<?> clz = Class.forName(dimenClass);
            Object obj = clz.newInstance();
            Field field = clz.getField(attrName);
            int id = Integer.parseInt(field.get(obj).toString());
            return context.getResources().getDimensionPixelSize(id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defaultV;
    }

    public  float getHorizontalScaleV(){

        return ( (float)displayMetricsWidth)/STANDARD_WIDTH;
    }
    public  float getVerticalScaleV(){

        return  ((float)displayMetricsHeight)/(STANDARD_HEIGHT-getSystemBarHeight(mContext));
    }

}

<?xml version="1.0" encoding="utf-8"?>
<com.example.screenscale.NewRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:text="Hello World!"
     />
    <TextView
        android:layout_marginTop="100px"
        android:layout_width="200px"
        android:layout_height="200px"
        android:text="Hello World!"
        />

</com.example.screenscale.NewRelativeLayout>
发布了134 篇原创文章 · 获赞 197 · 访问量 41万+

猜你喜欢

转载自blog.csdn.net/u011733020/article/details/103359569