Android 屏幕適配(簡單、成本低)

Android機型各種各樣,在適配的過程中不僅要考慮分辨率、長寬比、還要考慮屏幕密度,尤其是屏幕密度會導致不同手機上的顯示效果不同,有一種比較好的適配方式,在適配中通過density換算可以實現在所有所有手機上寬度都視爲360dp,高度則按寬度的放大縮小比例去放大和縮小,這是豎屏的情況,橫屏則可以將高度視爲720dp,寬度則一樣去按高度的比例去縮放,這樣帶來的好處就是控件,圖片按相同比例縮放,不會變形,同時忽略了屏幕密度的影響,讓控件和整個屏幕的相對比例和相對位置可以很好地適配。

實現原理和概念參考:https://www.jianshu.com/p/55e0fca23b4f

光講可能沒有感覺,放出實際效果看看:

圖一:是開發時預覽圖

圖2:是沒做什麼適配,dp的自適應結果,如果要達到與設計相同的結果是可以採取一些其他的適配方法,比如說按線性佈局的比例去佈局,按照約束佈局固定於邊界距離等,也是有很多方法,不過我用過的方法相對來說比較麻煩,而且有事會過度重繪導致界面性能較低。

圖三:是使用該適配方案

可以看出這種方法已經能達到很好的適配效果,相對來說比較簡單,代碼量很少,不過在保證寬度適配的同時,由於手機的長寬比不同,所以高度不會完全適配。這也是可以通過一些方法解決的,要根據實際佈局去做。

我把這個方法封裝了一個工具類,根據傳參不同是適配橫屏和豎屏,可以直接用,

DensityUtil類:
package com.example.administrator.densitytest;

import android.app.Activity;
import android.app.Application;
import android.content.ComponentCallbacks;
import android.content.res.Configuration;
import android.util.DisplayMetrics;

public class DensityUtil {

    private static float sNoncompatDensity;
    private static float sNoncompatScaledDensity;

    public static void setCustomDensity(Activity activity, final Application application, int direction){//direction:0-豎屏,1-橫屏
        final DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();

        if(sNoncompatDensity == 0){
            sNoncompatDensity = appDisplayMetrics.density;
            sNoncompatScaledDensity = appDisplayMetrics.scaledDensity;
            application.registerComponentCallbacks(new ComponentCallbacks() {
                @Override
                public void onConfigurationChanged(Configuration newConfig) {
                    if(newConfig != null && newConfig.fontScale >0 ){
                        sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
                    }
                }

                @Override
                public void onLowMemory() {

                }
            });
        }

        float targetDensity = appDisplayMetrics.widthPixels/360;
        if(direction==1){//橫屏
            targetDensity = appDisplayMetrics.widthPixels/640;
        }
//        final float targetDensity = appDisplayMetrics.widthPixels/360;
//        final float targetDensity = appDisplayMetrics.widthPixels/640;
        final int targetDensityDpi = (int)(160*targetDensity);
        final float targetScaledDensity = targetDensity * (sNoncompatScaledDensity/sNoncompatDensity);

        appDisplayMetrics.density = appDisplayMetrics.scaledDensity = targetDensity;
        appDisplayMetrics.densityDpi = targetDensityDpi;
        appDisplayMetrics.scaledDensity = targetScaledDensity;

        final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
        activityDisplayMetrics.density = activityDisplayMetrics.scaledDensity = targetDensity;
        activityDisplayMetrics.densityDpi = targetDensityDpi;
        activityDisplayMetrics.scaledDensity = targetScaledDensity;
    }
}
MainActivity:
package com.example.administrator.densitytest;


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DensityUtil.setCustomDensity(this,getApplication(),0);
        setContentView(R.layout.activity_main);
    }
}

Demo地址:https://github.com/han103070/DensityTest

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章