android 屏幕適配一:經過自定義View的方式實現適配

實現原理:以一個特定的寬度尺寸的設備爲參考,在View加載的過程當中,根據當前設備的實際像素換算出目標像素,再做用到控件上。android

一般UI給咱們的設計稿只有一種像素的標準,例如720 * 1280。 例如在設計稿上有一個控件寬度爲屏幕尺寸的一半,即360px,假設咱們真機的屏幕尺寸爲1080 * 1920像素,咱們再佈局中設置控件尺寸也爲360px,則顯示爲屏幕的三分之一。可是咱們想要效果仍然是顯示屏幕的一半。即寬度應該設置爲540px,這裏的540px是如何獲得的呢,這就是經過真實屏幕尺寸與參考設計稿的尺寸比例來獲得的,即:(1080/720)*360 = 540。bash

下面經過代碼來實現這一功能:app

public class Utils {
    private static Utils utils;

    //這是設計稿參考的寬高
    private static final float STANDARD_WIDTH = 720;
    private static final float STANDARD_HEIGHT = 1080;

    //這裏是屏幕的顯示寬高
    private int mDisPlayWidth;
    private int mDisPlayHeight;

    public static Utils getInstance(Context context) {
        if (utils == null) {
            utils = new Utils(context.getApplicationContext()); //獲取application的context是防止內存泄漏
        }
        return utils;
    }

    private Utils(Context context) {
        //獲取屏幕的寬高
        if (mDisPlayHeight == 0 || mDisPlayWidth == 0) { //寬高還未賦值
            WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            if (manager != null) {
                DisplayMetrics displayMetrics = new DisplayMetrics();
                manager.getDefaultDisplay().getMetrics(displayMetrics); //此時displayMetrics就能夠獲取到屏幕寬高信息了
                if (displayMetrics.widthPixels > displayMetrics.heightPixels) {
                    //橫屏
                    mDisPlayWidth = displayMetrics.heightPixels;
                    mDisPlayHeight = displayMetrics.widthPixels - getStatusBarHeight(context);
                } else {
                    //豎屏
                    mDisPlayWidth = displayMetrics.widthPixels;
                    mDisPlayHeight = displayMetrics.heightPixels - getStatusBarHeight(context);
                }
            }
        }
    }

    //獲取狀態欄高度
    public int getStatusBarHeight(Context context) {
        int resID = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resID > 0) { //能夠獲取到狀態欄高度
            return context.getResources().getDimensionPixelSize(resID);
        }
        return 0;
    }

    //獲取水平方向的縮放比例
    public float getHorizontalScale() {
        return mDisPlayWidth / STANDARD_WIDTH;
    }

    //獲取垂直方向的縮放比例
    public float getVerticalScale() {
        return mDisPlayHeight / STANDARD_HEIGHT;
    }

}

複製代碼

Utils工具類用來計算設計稿屏幕分辨率和真實屏幕分辨率的比例。ide

下面以RelativeLayout爲例:工具

public class ScreenAdapterLayout extends RelativeLayout {

    private boolean flag;

    public ScreenAdapterLayout(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //計算寬高以前獲取縮放比例的值
        if (!flag) { //防止比例的計算屢次調用
            float scaleX = Utils.getInstance(getContext()).getHorizontalScale();
            float scaleY = Utils.getInstance(getContext()).getVerticalScale();
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                View child = getChildAt(i);
                LayoutParams params = (LayoutParams) child.getLayoutParams();
                params.width = (int) (params.width * scaleX);
                params.height = (int) (params.height * scaleY);
                params.leftMargin = (int) (params.leftMargin * scaleX);
                params.rightMargin = (int) (params.rightMargin * scaleX);
                params.topMargin = (int) (params.leftMargin * scaleY);
                params.bottomMargin = (int) (params.leftMargin * scaleY);
            }
            flag = true;
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
複製代碼

下面在資源佈局中使用ScreenAdapterLayout。佈局

這裏我設置的寬度爲360px,我手機的像素爲1080*2248,可是顯示的view的寬度仍然爲屏幕的一半。這是由於根據Utils把view的寬高作了換算。咱們不須要關注真實屏幕的分辨率。只須要根據設計稿的分辨率來設置view的寬高。ui

注:博主菜雞一個,第一次寫博客,但願獲得大佬的指點。輕點噴o(╥﹏╥)ospa

相關文章
相關標籤/搜索