Android 屏幕分辨率適配

前言

Android屏幕分辨率千奇百怪滑潘,怎么讓app在不同的分辨率的設(shè)備上“看起來一樣”呢班巩?
你也許還有以下疑惑:

  • px夕冲、dp氮兵、sp區(qū)別與作用
  • mipmap和drawable區(qū)別與作用
  • mdpi hdpi xhdpi的圖片資源有什么區(qū)別
  • 如何適配不同密度下的圖片資源
  • 不同分辨率的設(shè)備如何適配寬度
  • dpi是怎么確定的

這篇文章將會針對以上問題一一解答。

基本單位

px

Pixels 我們看到屏幕上的圖像由一個個像素組成耘擂,像素里包含色彩信息胆剧。
如常說的手機(jī)分辨率:1080 x 1920 指的是手機(jī)寬度可展示1080像素,高度可展示1920像素醉冤。

ppi

Pixels Per Inch 每英寸長度所具有的像素個數(shù)秩霍,單位面積內(nèi)像素越多,圖像顯示越清晰蚁阳。
ppi一般用在顯示器铃绒、手機(jī)、平板等描述屏幕精細(xì)度螺捐。

dpi

Dots Per Inch 每英寸長度所具有的點數(shù)颠悬。
dpi一般用來描述打印(書本定血、雜志赔癌、電報)的精細(xì)度

dp/dip

density-independent pixels (device-independent pixels 我查了一下,官網(wǎng)更多時候使用前者澜沟,有的時候也顯示后者)灾票,dip是縮寫,也可以更簡單些稱作dp茫虽。該單位的目的是屏蔽不同設(shè)備密度差異刊苍,后面細(xì)說。

sp

Scalable pixels 用于設(shè)置字體濒析,在用戶更改字體大小時候會適配正什。

簡單例子

澄清了基本概念,我們現(xiàn)在從一個例子開始說明以上單位之間的區(qū)別與聯(lián)系号杏。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/big"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <View
        android:layout_gravity="center"
        android:background="@color/green"
        android:layout_width="200px"
        android:layout_height="200px">
    </View>

</FrameLayout>

布局文件里有個View婴氮,長寬都是200px,分別在分辨率為480(寬)x800(高)簡稱A設(shè)備盾致、1080(寬)x1920(高)簡稱B設(shè)備莹妒,效果如下:


image.png

左邊是A設(shè)備,右邊是B設(shè)備绰上。問題出來了,同樣長寬都是200px渠驼,為啥A設(shè)備顯示很大蜈块,B設(shè)備顯示很小呢?你可能會說B設(shè)備的橫向分辨率1080比A設(shè)備的480大,所以在B設(shè)備上看起來比較小百揭。來看看A爽哎、B設(shè)備橫向到底是多少英寸,怎么來計算呢器一?這時候就需要用到ppi了课锌,既然知道橫向的像素點個數(shù),也知道每英寸能容納的像素點祈秕,當(dāng)然可以得知橫向的尺寸了渺贤。

DisplayMetrics.java
    /**
     * The exact physical pixels per inch of the screen in the X dimension.
     */
    public float xdpi;
    /**
     * The exact physical pixels per inch of the screen in the Y dimension.
     */
    public float ydpi;

其中一種方式獲取DisplayMetrics對象:

DisplayMetrics displayMetrics = getResources().getDisplayMetrics();

A設(shè)備寬度尺寸:480(px)/240(ppi)=2inch
B設(shè)備寬度尺寸:1080(px)/420(ppi)=2.5inch
可以看出,A请毛、B設(shè)備尺寸差別不大志鞍。A設(shè)備ppi=240 B設(shè)備ppi=420,明顯地看出B設(shè)備單位長度上比A設(shè)備能夠容納更多的像素方仿,因此同樣的200px,B設(shè)備只需要較小的尺寸就能夠顯示仙蚜,因此在B設(shè)備上的view看起來比A設(shè)備小很多此洲。
知道了問題的原因,然而顯示的效果卻不能接受委粉。

我們想要的效果是:同一大小的view在不同的設(shè)備上“看起來一樣大”

我們總不能自己判斷每個設(shè)備的ppi呜师,然后計算實際需要多少像素,再動態(tài)設(shè)置view的大小吧艳丛,那layout里的靜態(tài)布局大小就無法動態(tài)更改適應(yīng)了匣掸。想當(dāng)然的能有一個統(tǒng)一的地方替我們轉(zhuǎn)換,沒錯氮双!Android系統(tǒng)已經(jīng)幫我們實現(xiàn)了轉(zhuǎn)換碰酝。接下來就是dpi、dp出場了戴差。

引入dpi送爸、dp

Android系統(tǒng)使用dpi來描述屏幕的密度,使用dp來描述密度與像素的關(guān)系暖释。
A設(shè)備dpi=240
B設(shè)備dpi=420
Android系統(tǒng)最終識別的單位是px袭厂,怎么將dpi和px關(guān)聯(lián)起來呢?球匕,答案是dp纹磺。
Android規(guī)定當(dāng)dpi=160時,1dp=1px亮曹,當(dāng)dpi=240時橄杨,1dp=1.5px秘症,依此類推,并且給各個范圍的dpi取了簡易的名字加以直觀的識別式矫,如120<dpi<=160乡摹,稱作為mdpi,120<dpi<=240 稱作hdpi采转,最終形成如下規(guī)則:

ldpi(value <= 120 dpi)
mdpi(120 dpi < value <= 160 dpi)
hdpi(160 dpi < value <= 240 dpi)
xhdpi(240 dpi < value <= 320 dpi)
xxhdpi(320 dpi < value <= 480 dpi)
xxxhdpi(480 dpi < value <= 640 dpi)

現(xiàn)在知道了dp能夠在不同dpi設(shè)備上對應(yīng)不同px聪廉,相當(dāng)于中間轉(zhuǎn)換層,我們只需要將view長寬單位設(shè)置為合適的dp故慈,就無需關(guān)注設(shè)備之間密度差異板熊,系統(tǒng)會幫我們完成dp-px轉(zhuǎn)換。將我們之前的例子稍微更改惯悠,再看看效果驗證一下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/big"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <View
        android:layout_gravity="center"
        android:background="@color/green"
        android:layout_width="200dp"
        android:layout_height="200dp">
    </View>

</FrameLayout>

image.png

這里看起來還是不一樣呢?[注1]
綜上所述邻邮,dp作為中間單位為我們屏蔽了不同密度設(shè)備差異,這也是為啥dp/dip叫做“設(shè)備(密度)無關(guān)像素”的原因克婶。

mipmap圖片資源文件

通過上面對dp的了解筒严,我們知道在設(shè)定view大小、間距時使用dp能最大限度地屏蔽設(shè)備密度之間的差異情萤⊙纪埽可能你就會問了,那bitmap展示的時候如何適配不同密度的設(shè)備呢筋岛?

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(bitmap.getWidth(), bitmap.getHeight());
    }

    private void init() {
        String path = Environment.getExternalStorageDirectory() + "/Download/photo1.jpg";
        bitmap = BitmapFactory.decodeFile(path);
        paint = new Paint();
        paint.setAntiAlias(true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        RectF rectF = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
        canvas.drawBitmap(bitmap, src, rectF, paint);
    }

自定義view從磁盤上加載一張圖片娶视,并將之顯示在view上,view的大小決定于bitmap大小睁宰。依舊以上述A肪获、B設(shè)備為例,展示結(jié)果如下:


image.png

左邊是A設(shè)備柒傻,右邊是B設(shè)備孝赫。
明顯地看出,在A設(shè)備顯示比B設(shè)備大很多红符,實際上和我們之前用px來描述view的大小原理是一樣的青柄,bitmap的寬、高都是px在描述预侯,而bitmap決定了view的寬致开、高,最終導(dǎo)致A設(shè)備和B設(shè)備上的view大形凇(寬双戳、高像素)是一樣的,而它們屏幕密度又不相同糜芳,因此產(chǎn)生了差異飒货。
那不會每次都需要我們自己根據(jù)屏幕密度來轉(zhuǎn)換bitmap大小吧千诬?幸運(yùn)的是,Android已經(jīng)為我們考慮到了膏斤。


image.png

如上圖,在Android Studio創(chuàng)建工程的時候邪驮,默認(rèn)在res下創(chuàng)建mipmap目錄莫辨,這些mipmap目錄按照密度分為mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi,看起來都在“一個“mipmap”目錄下毅访,實際上分為不同的目錄:
image.png

生成不同密度的目錄有什么作用沮榜?
A設(shè)備dpi=240,根據(jù)dpi范圍喻粹,屬于hdpi
B設(shè)備dpi=420蟆融,根據(jù)dpi范圍,屬于xxhdpi
圖片原始尺寸:photo1.jpg(寬高 172px-172px)
當(dāng)我們想要在不同密度設(shè)備上顯示同一張圖片并且想要“看起來一樣大時”守呜。假設(shè)設(shè)計的時候以hdpi為準(zhǔn)型酥,放置photo1.jpg為172*172,那么根據(jù)計算規(guī)則在xxhdpi上需要設(shè)置photo1.jpg為:

scale = 480 / 240 = 2
width = 172 * 2 = 344
height = 172 * 2= 344
注:這里為什么要放大查乒?可以這么理解弥喉,因為B設(shè)備密度大,通常來說密度越大單位尺寸內(nèi)需要的像素越多玛迄,假設(shè)A設(shè)備上172*172占據(jù)1inch面積由境,那么為了能夠在B設(shè)備上填充滿相同的面積需要更多的像素,因此B設(shè)備上的圖片分辨率應(yīng)該更大(這里說的通常是因為真正決定設(shè)備單位尺寸內(nèi)容納的像素個數(shù)的因素是ppi蓖议,有些設(shè)備dpi比較大虏杰,但是ppi反而小)

現(xiàn)在hdpi和xxhdpi目錄下分別存放了同名圖片:photo1.jpg勒虾,只是大小不同纺阔。當(dāng)程序運(yùn)行的時候:

A設(shè)備發(fā)現(xiàn)自己密度屬于hdpi,它會直接到hdpi下尋找對應(yīng)的photo1.jpg并顯示
B設(shè)備發(fā)現(xiàn)自己密度屬于xxhdpi从撼,它會直接到xxhdpi下尋找對應(yīng)的photo1.jpg并顯示

來看看效果:


image.png

左邊A設(shè)備州弟,右邊B設(shè)備
針對不同的密度設(shè)計不同的圖片大小,最大限度保證了同一圖片在不同密度設(shè)備上表現(xiàn)“看起來差不多大”低零。
來看看A婆翔、B設(shè)備上圖片占內(nèi)存大小:

A設(shè)備 172 * 172 * 4 = 118336 ≈ 116k
B設(shè)備 344 * 344 * 4 = 473344 ≈ 462k
注:解析bitmap時掏婶,默認(rèn)inPreferredConfig=ARGB_8888啃奴,也就是每個像素有4個字節(jié)來存儲

說明在B設(shè)備上顯示photo1.jpg需要更多的內(nèi)存。
上邊只是列舉了hdpi雄妥、xxhdipi最蕾,同理對于mdpi依溯、xhdpi、xxxhdpi根據(jù)規(guī)則放入相應(yīng)大小的圖片瘟则,程序會根據(jù)不同的設(shè)備密度從對應(yīng)的mipmap文件夾下加載資源黎炉。如此一來,我們無需關(guān)注bitmap在不同密度設(shè)備上顯示問題了醋拧。

圖片資源文件的加載

在mipmap各個文件夾下都放置同一套資源的不同尺寸文件似乎有點太占apk大小慷嗜,能否只放某個密度下圖片,其余的靠系統(tǒng)自己適配呢丹壕?
現(xiàn)在只保留hdpi下的photo1.jpg圖片庆械,看看在A、B設(shè)備上運(yùn)行情況如何:


image.png

看起來和上張圖差不多菌赖,說明系統(tǒng)會幫我們適配B設(shè)備上的圖片缭乘。
再來看看A、B設(shè)備上圖片占內(nèi)存大辛鹩谩:
先看A設(shè)備:


image.png

再看B設(shè)備:
image.png

A設(shè)備 172 * 172 * 4 = 118336 ≈ 116k
B設(shè)備 301 * 301 * 4 = 362404 ≈ 354k

對比photo1.jpg 分別放在hdpi堕绩、xxhdpi和只放在hdpi下可以看出:B設(shè)備上圖片所占內(nèi)存變小了。為什么呢辕羽?接下來從源碼里尋找答案逛尚。

構(gòu)造Bitmap

Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.photo1);

A、B設(shè)備同樣加載hdpi/photo1.jpg刁愿,返回的bitmap大小不相同绰寞,我們從這方法開始一探究竟。

    public static Bitmap decodeResource(Resources res, int id, BitmapFactory.Options opts) {
        validate(opts);
        Bitmap bm = null;
        InputStream is = null;

        try {
            
            final TypedValue value = new TypedValue();
            //根據(jù)資源id铣口,構(gòu)造Value對象滤钱,這里面需要關(guān)注的變量:density
            is = res.openRawResource(id, value);
            bm = decodeResourceStream(res, value, is, null, opts);
        } catch (Exception e) {
            /*  do nothing.
                If the exception happened on open, bm will be null.
                If it happened on close, bm is still valid.
            */
        } finally {
            try {
                if (is != null) is.close();
            } catch (IOException e) {
                // Ignore
            }
        }

        if (bm == null && opts != null && opts.inBitmap != null) {
            throw new IllegalArgumentException("Problem decoding into existing bitmap");
        }

        return bm;
    }
    public static Bitmap decodeResourceStream(@Nullable Resources res, @Nullable TypedValue value,
                                              @Nullable InputStream is, @Nullable Rect pad, @Nullable BitmapFactory.Options opts) {
        validate(opts);
        if (opts == null) {
            opts = new BitmapFactory.Options();
        }
        
        if (opts.inDensity == 0 && value != null) {
            //通過value里的density給options里的inDensity賦值
            final int density = value.density;
            if (density == TypedValue.DENSITY_DEFAULT) {
                opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
            } else if (density != TypedValue.DENSITY_NONE) {
                opts.inDensity = density;
            }
        }

        if (opts.inTargetDensity == 0 && res != null) {
            //獲取設(shè)備屏幕密度并賦予opts.inTargetDensity
            opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
        }

        //確定option inDensity、inTargetDensity 后傳入jni層加載bitmap
        return decodeStream(is, pad, opts);
    }

上面涉及到的關(guān)鍵點是density脑题,分別是TypedValue的density和Options的density件缸。
先來看看TypedValue density:

    /**
     * If the Value came from a resource, this holds the corresponding pixel density.
     * */
    public int density;

簡單解釋:表示該資源從哪個密度文件夾下取的;比如A叔遂、B設(shè)備取hdpi下的photo1.jpg他炊,那么此時density=240

再來看看Options density

* The pixel density to use for the bitmap.  This will always result
* in the returned bitmap having a density set for it

public int inDensity;

* The pixel density of the destination this bitmap will be drawn to.
* This is used in conjunction with {@link #inDensity} and
* {@link #inScaled} to determine if and how to scale the bitmap before
* returning it.

public int inTargetDensity;

簡單解釋:inDensity表示該資源來源于哪個密度的文件夾,該值從TypedValue獲纫鸭琛痊末;inTargetDensity表示該資源將要顯示在哪個密度的設(shè)備上。在構(gòu)造Bitmap時哩掺,會根據(jù)inDensity與inTargetDensity決定Bitmap放大縮寫的倍數(shù)凿叠。
計算公式如下:
needSize = (int)(size * ((float)inTargetDensity / inDensity) + 0.5) (四舍五入)

現(xiàn)在分析B設(shè)備加載hdpi/photo1.jpg如何做的:

1、hdpi密度是240 因此Options.inDesnity = 240
2、B設(shè)備密度是420 因此Options.inTargetDensity = 420;
3盒件、B設(shè)備返回bitmap大小=172 * 420 / 240 = 301px

和我們之前調(diào)試的結(jié)果一致蹬碧。

Density匹配規(guī)則

B設(shè)備是怎么決定使用hdpi下的圖片資源呢?
根據(jù)實驗(嘗試找了源碼炒刁,沒怎么看懂恩沽,因此只是做了實驗,可能在不同密度設(shè)備上找尋規(guī)則不一樣):B設(shè)備先找屬于自己密度范圍文件夾下的圖片翔始,B設(shè)備屬于xxhdpi飒筑,先查看xxhdpi有沒有photo1.jpg,如果沒有則往更高的密度找绽昏,比它高的密度是xxxhdpi,還是沒有俏脊,則往低密度找全谤,找xhdpi,沒有再找hdpi爷贫,找到了則返回構(gòu)造好的TypedValue认然,剩下的就是我們前面分析的。
既然我們只想放某個密度下的一份切圖漫萄,該放哪個密度下呢卷员?從系統(tǒng)尋找規(guī)則看,更推薦放置在更高密度下的腾务,因為如果放在低密度下毕骡,那么當(dāng)運(yùn)行在高密度設(shè)備上時,圖片會進(jìn)行放大岩瘦,可能導(dǎo)致不清晰未巫。我一般習(xí)慣放在xxhdpi下。

drawable和mipmap不同密度文件夾

Android Studio默認(rèn)創(chuàng)建了不同密度的mipmap文件夾启昧,默認(rèn)放置了ic_launcher.png叙凡。我們普通的切圖該放drawable還是mipmap下呢?對于這個問題網(wǎng)上也是眾說紛紜密末,實際上對于我們來說握爷,關(guān)注的重點是圖片放在drawable或者mipmap,加載出來bitmap是否有差異严里,如果沒有差異放在哪就看習(xí)慣了新啼。通過實踐,普通的切圖放drawable和mipmap下加載出來的bitmap是沒有差異的田炭,只不過用drawable的話需要自己創(chuàng)建不同密度的文件夾师抄。我習(xí)慣于放在drawable下(啟動圖標(biāo)logo還是放在mipmap下)。

屏幕寬度適配

前邊[注1]留了個問題教硫,我們使用dp來表示view的大小了叨吮,為啥兩個看起來還是有些差距辆布?下面我們更加直觀地看一個例子。
A設(shè)備dpi=240 密度1.5 分辨率(寬高px):480 * 800
B設(shè)備dpi=420 密度2.625 分辨率(寬高px):1080 * 1794
換算成dp
A設(shè)備分辨率:320dp * 533dp
B設(shè)備分辨率:411dp * 683dp
依舊是上邊的例子:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/big"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <View
        android:id="@+id/iv"
        android:background="@color/green"
        android:layout_gravity="center"
        android:layout_width="320dp"
        android:layout_height="320dp"/>

</FrameLayout>

將view寬高分別設(shè)置為320dp茶鉴,看看效果:


image.png

左邊A設(shè)備锋玲,右邊B設(shè)備
可以看出同樣的320dp大小,A設(shè)備鋪滿了屏幕涵叮,而B設(shè)備沒有惭蹂。這效果顯然是不能接受的,Android考慮到不同設(shè)備寬高不同割粮,推出了"寬高限定符"盾碗。以A、B設(shè)備為例:
在res文件夾下創(chuàng)建文件夾:

values-800x480
values-1794x1080

假設(shè)設(shè)計師出圖是按照800x480舀瓢,那么我們創(chuàng)建dimen文件的時候

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="px1">1px</dimen>
    <dimen name="px2">1px</dimen>
    ...
    <dimen name="px100">100px</dimen>
    <dimen name="px101">101px</dimen>
</resources>

該文件放在values-800x480文件夾下廷雅。
根據(jù)分辨率比例算出1794x1080的dimen值

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="px1">2.24px</dimen>
    <dimen name="px2">4.48px</dimen>
    ...
    <dimen name="px100">224px</dimen>
    <dimen name="px101">226.24px</dimen>
</resources>

這樣子,A京髓、B設(shè)備加載資源的時候使用對應(yīng)分辨率限定符下的px航缀,如果找不到再找默認(rèn)值,可以在一定程度上解決屏幕寬高碎片化適配問題堰怨。
但是這樣子的限定比較嚴(yán)格芥玉,需要測試各種分辨率,后來Android又推出了"smallest-width"簡稱最小寬度限制备图。
A設(shè)備寬320dp
B設(shè)備寬411dp
假設(shè)設(shè)計師切圖標(biāo)準(zhǔn)屏幕寬是320dp(A設(shè)備)灿巧,那么可以定義如下dimen.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="dp1">1dp</dimen>
    <dimen name="dp2">2dp</dimen>
    <dimen name="dp320">320dp</dimen>
</resources>

該文件放在values-sw320dp文件夾下
根據(jù)規(guī)則,計算B設(shè)備dimen.xml

scale = targetWidth/baseWidth=411/320≈1.28
value = scale * baseValue
得出:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="dp1">1dp</dimen>
    <dimen name="dp2">3dp</dimen>
    <dimen name="dp320">410dp</dimen>
</resources>

現(xiàn)在我們繼續(xù)來看之前的view

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/big"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <View
        android:id="@+id/iv"
        android:background="@color/green"
        android:layout_gravity="center"
        android:layout_width="@dimen/dp320"
        android:layout_height="@dimen/dp320"/>

</FrameLayout>

通過對dimen引用揽涮,A設(shè)備尋找和自己寬度一樣的dimen文件砸烦,找到values-sw320dp,dp320=320dp绞吁。B設(shè)備尋找和自己寬度一樣的dimen文件幢痘,找到values-sw411dp,dp320=410dp家破。這樣子同樣的dp320颜说,得出不同的值,就適配了屏幕寬度不同的問題汰聋。
看看效果:


image.png

這次B設(shè)備也鋪滿了屏寬门粪。

1、如果B設(shè)備找不到values-sw411dp烹困,那么會繼續(xù)往下尋找(比自己寬度小的)玄妈,比如找到values-sw390dp,就會使用里面的值
2、為什么高度沒有限定呢拟蜻?因為對于豎直方向上來說绎签,我們是可以設(shè)計為滾動模式的,因此對于高度的適配沒那么敏感

綜上酝锅,為了適配不同屏幕大小诡必,推薦使用dp+smallest-width。

如何獲取dpi

DisplayMetrics.java
    private static int getDeviceDensity() {
        // qemu.sf.lcd_density can be used to override ro.sf.lcd_density
        // when running in the emulator, allowing for dynamic configurations.
        // The reason for this is that ro.sf.lcd_density is write-once and is
        // set by the init process when it parses build.prop before anything else.
        return SystemProperties.getInt("qemu.sf.lcd_density",
                SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
    }

獲取設(shè)備dpi最終都是從這方法獲取的搔扁,實際上就是讀取系統(tǒng)的配置文件爸舒。因此我們也可以通過adb shell 獲取:

HWTAS:/ $ wm size                                                                                                                                                                                   
Physical size: 1080x2340
HWTAS:/ $ 
HWTAS:/ $ getprop ro.sf.lcd_density
480
HWTAS:/ $ wm density 
Physical density: 480
HWTAS:/ $ 

可以看出dpi是系統(tǒng)配置好的稿蹲,當(dāng)然有些手機(jī)是可以設(shè)置分辨率的扭勉,設(shè)置之后我們查看分辨率:

HWTAS:/ $ wm density                                                                                                                                                                                
Physical density: 480
Override density: 320
HWTAS:/ $ 
HWTAS:/ $ 
HWTAS:/ $ wm size                                                                                                                                                                                   
Physical size: 1080x2340
Override size: 720x1560
HWTAS:/ $ 

分辨率變低了,dpi也變小了苛聘。

您若喜歡剖效,請點贊、關(guān)注焰盗,您的鼓勵是我前進(jìn)的動力

持續(xù)更新中,和我一起步步為營系統(tǒng)咒林、深入學(xué)習(xí)Android/Java

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末熬拒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子垫竞,更是在濱河造成了極大的恐慌澎粟,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欢瞪,死亡現(xiàn)場離奇詭異活烙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)遣鼓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門啸盏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人骑祟,你說我怎么就攤上這事回懦。” “怎么了次企?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵怯晕,是天一觀的道長。 經(jīng)常有香客問我缸棵,道長舟茶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮吧凉,結(jié)果婚禮上隧出,老公的妹妹穿的比我還像新娘。我一直安慰自己客燕,他們只是感情好鸳劳,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著也搓,像睡著了一般赏廓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上傍妒,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天幔摸,我揣著相機(jī)與錄音,去河邊找鬼颤练。 笑死既忆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嗦玖。 我是一名探鬼主播患雇,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宇挫!你這毒婦竟也來了苛吱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤器瘪,失蹤者是張志新(化名)和其女友劉穎翠储,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體橡疼,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡援所,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了欣除。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片住拭。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖历帚,靈堂內(nèi)的尸體忽然破棺而出废酷,到底是詐尸還是另有隱情,我是刑警寧澤抹缕,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布澈蟆,位于F島的核電站,受9級特大地震影響卓研,放射性物質(zhì)發(fā)生泄漏趴俘。R本人自食惡果不足惜睹簇,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寥闪。 院中可真熱鬧太惠,春花似錦、人聲如沸疲憋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昧碉。三九已至鸥跟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秋忙,已是汗流浹背彩掐。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留灰追,地道東北人堵幽。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像弹澎,于是被迫代替她去往敵國和親朴下。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容