Android屏幕適配之--通過修改系統(tǒng)的屏幕像素比來實(shí)現(xiàn)屏幕的適配效果

Android屏幕適配之--通過修改系統(tǒng)的屏幕像素比來實(shí)現(xiàn)屏幕的適配效果

關(guān)于Android中dip,dpi,density,px的詳細(xì)解釋參考簡(jiǎn)書前輩的文章Android開發(fā)中dip,dpi,density,px等詳解

當(dāng)然在下面的代碼中,density代表的是縮放比,densityDpi代表的是像素密度(就是一個(gè)dp中有多少個(gè)px),Android官方中是以160為基準(zhǔn)dpi

做一個(gè)簡(jiǎn)要的說明:在顯示中,實(shí)際都是以像素px為單位來對(duì)控件的大小進(jìn)行指定的,所以數(shù)值在換算的公式是這樣的

實(shí)際顯示的像素值px = 縮放比 * 設(shè)置的dp值

縮放比 = 實(shí)際的dpi / 160(基準(zhǔn)dpi)

代碼不多,先直接把整個(gè)類的代碼貼上來吧

public class DensityUtil {

//屏幕的參考寬度值,單位是dp
private static float STAND_WIDTH = 320;

//系統(tǒng)原來的像素縮放比
private static float appDensity;
private static float appScaleDensity;   //字體縮放比

public static void setDensity(final Application application, Activity activity) {

    final DisplayMetrics appMetrics = application.getResources().getDisplayMetrics();
    if (appDensity == 0) {
        //獲取系統(tǒng)本來的像素縮放比和字體縮放比
        appDensity = appMetrics.density;
        appScaleDensity = appMetrics.scaledDensity;
    }

    application.registerComponentCallbacks(new ComponentCallbacks() {
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            //代表字體大小進(jìn)行了更改,需要對(duì)字體縮放比進(jìn)行重新賦值
            if(newConfig != null && newConfig.fontScale > 0){
                appScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
            }
        }
        @Override
        public void onLowMemory() {

        }
    });

    //通過實(shí)際的屏幕大小來計(jì)算新的屏幕像素縮放比
    float targetDensity = appMetrics.widthPixels / STAND_WIDTH;
    float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
    float targetDensityDpi = targetDensity * 160;

    //將獲取到的新的縮放比設(shè)置回去
    DisplayMetrics actMetrics = activity.getResources().getDisplayMetrics();
    actMetrics.density = targetDensity;
    actMetrics.densityDpi = (int) targetDensityDpi;
    actMetrics.scaledDensity = targetScaleDensity;
    }
}

在調(diào)用的時(shí)候,要在目標(biāo)界面Activity的setContentView代碼之前進(jìn)行調(diào)用

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    DensityUtil.setDensity(getApplication(),this);
    setContentView(R.layout.activity_density);
}

整個(gè)思路就是先拿到整個(gè)屏幕的像素值,然后除以參照的設(shè)計(jì)圖中的設(shè)備寬度dp值,這樣就可以得到一個(gè)目標(biāo)的縮放比,通過這個(gè)縮放比就可以得到字體的縮放比和像素密度,然后在把得到的這幾個(gè)值給設(shè)置回去。

疑問

可能在代碼中會(huì)有這樣的疑問,為什么要先獲取Application的appDensity、appScaleDensity這些參數(shù),經(jīng)過換算后替換成Activity的Density、ScaleDensity,而不是一開始直接獲取Activity的DisplayMetrics,然后從這個(gè)DisplayMetrics中提取Density、ScaleDensity等屬性,然后直接修改呢?

解答

是這樣的,當(dāng)你改了一個(gè)Activity后,整個(gè)app所有的界面都會(huì)發(fā)生變化,比如A activity的density修改后就,bActivity的也相應(yīng)發(fā)生修改,但是application的density并沒有變化,如果還需要再縮放那就是在已經(jīng)縮放一次的基礎(chǔ)上還會(huì)再乘上一個(gè)對(duì)應(yīng)的倍數(shù),所有這里使用app的DisplayMetrics主要是為了確保計(jì)算正確

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容