Android 屏幕適配方案

前言

本文為自身的總結(jié)與結(jié)合其他文章引用而成,分別為:

一、為什么要適配

由于Android系統(tǒng)的開(kāi)放性,任何用戶(hù)、開(kāi)發(fā)者、硬件廠商、運(yùn)營(yíng)商都可以對(duì)Android系統(tǒng)和硬件進(jìn)行定制,修改成他們想要的樣子。
那么這種“碎片化”到達(dá)什么程度呢?


Android 碎片化

以上每一個(gè)矩形都代表一種機(jī)型,且它們屏幕尺寸、屏幕分辨率大相徑庭。隨著Android設(shè)備的增多,設(shè)備碎片化、系統(tǒng)碎片化、屏幕尺寸碎片化、屏幕碎片化的程度也在不斷加深。

備注:

  1. Android系統(tǒng)碎片化:基于Google原生系統(tǒng),小米定制的MIUI、魅族定制的flyme、華為定制的EMUI等等;
  2. Android機(jī)型屏幕尺寸碎片化:5寸、5.5寸、6寸等等;
  3. Android屏幕分辨率碎片化:320x480、480x800、720x1280、1080x1920等;

當(dāng)Android系統(tǒng)、屏幕尺寸、屏幕密度出現(xiàn)碎片化的時(shí)候,就很容易出現(xiàn)同一元素在不同手機(jī)上顯示不同的問(wèn)題。試想一下這么一個(gè)場(chǎng)景:
為4.3寸屏幕準(zhǔn)備的UI設(shè)計(jì)圖,運(yùn)行在5.0寸的屏幕上,很可能在右側(cè)和下側(cè)存在大量的空白;而5.0寸的UI設(shè)計(jì)圖運(yùn)行到4.3寸的設(shè)備上,很可能顯示不下。

為了保證用戶(hù)獲得一致的用戶(hù)體驗(yàn)效果,使得某一元素在Android不同尺寸、不同分辨率的、不同系統(tǒng)的手機(jī)上具備相同的顯示效果,能夠保持界面上的效果一致,我們需要對(duì)各種手機(jī)屏幕進(jìn)行適配!

二、基本概念

1、像素(px):

  • 含義:通常所說(shuō)的像素,就是CCD/CMOS上光電感應(yīng)元件的數(shù)量,一個(gè)感光元件經(jīng)過(guò)感光,光電信號(hào)轉(zhuǎn)換,A/D轉(zhuǎn)換等步驟以后,在輸出的照片上就形成一個(gè)點(diǎn),我們?nèi)绻延跋穹糯髷?shù)倍,會(huì)發(fā)現(xiàn)這些連續(xù)色調(diào)其實(shí)是由許多色彩相近的小方點(diǎn)所組成,這些小方點(diǎn)就是構(gòu)成影像的最小單位“像素”(Pixel)。簡(jiǎn)而言之,像素就是手機(jī)屏幕的最小構(gòu)成單元。
  • 單位:px(pixel),1px = 1像素點(diǎn)
    一般情況下UI設(shè)計(jì)師的設(shè)計(jì)圖會(huì)以px作為統(tǒng)一的計(jì)量單位。

2、分辨率:

  • 含義:手機(jī)在橫向、縱向上的像素點(diǎn)數(shù)總和
    一般描述成 寬*高 ,即橫向像素點(diǎn)個(gè)數(shù) * 縱向像素點(diǎn)個(gè)數(shù)(如1080 x 1920)。
  • 單位:px(pixel),1px = 1像素點(diǎn)

3、屏幕尺寸(in):

  • 含義:手機(jī)對(duì)角線的物理尺寸
  • 單位 英寸(inch),一英寸大約2.54cm
    常見(jiàn)的尺寸有4.7寸、5寸、5.5寸、6寸

4、屏幕像素密度(dpi):

  • 含義:每英寸的像素點(diǎn)數(shù)。
    例如每英寸內(nèi)有160個(gè)像素點(diǎn),則其像素密度為160dpi。
  • 單位:dpi(dots per inch)
  • 計(jì)算公式: 像素密度 = 像素 / 尺寸 (dpi = px / in)
  • 標(biāo)準(zhǔn)屏幕像素密度(mdpi): 每英寸長(zhǎng)度上還有160個(gè)像素點(diǎn)(160dpi),即稱(chēng)為標(biāo)準(zhǔn)屏幕像素密度(mdpi)。
密度類(lèi)型 代表的分辨率(px) 屏幕像素密度(dpi)
低密度(ldpi) 240 x 320 120
中密度(mdpi) 320 x 480 160
高密度(hdpi) 480 x 800 240
超高密度(xhdpi) 720 x 1280 320
超超高密度(xxhdpi) 1080 x 1920 480

屏幕尺寸、分辨率、像素密度三者關(guān)系

一部手機(jī)的分辨率是寬x高,屏幕大小是以寸為單位,那么三者的關(guān)系是:

image

假設(shè)一部手機(jī)的分辨率是1080x1920(px),屏幕大小是5寸

5寸屏幕像素密度

5、密度無(wú)關(guān)像素(dp):

  • 含義:density-independent pixel,叫dp或dip,與終端上的實(shí)際物理像素點(diǎn)無(wú)關(guān)
  • 單位:dp,可以保證在不同屏幕像素密度的設(shè)備上顯示相同的效果,是安卓特有的長(zhǎng)度單位。
  • 場(chǎng)景例子:假如同樣都是畫(huà)一條長(zhǎng)度是屏幕一半的線,如果使用px作為計(jì)量單位,那么在480x800分辨率手機(jī)上設(shè)置應(yīng)為240px;在320x480的手機(jī)上應(yīng)設(shè)置為160px,二者設(shè)置就不同了;如果使用dp為單位,在這兩種分辨率下,160dp都顯示為屏幕一半的長(zhǎng)度。
  • dp與px的轉(zhuǎn)換:1dp = (dpi / 160 ) * 1px;
密度類(lèi)型 代表的分辨率(px) 屏幕密度(dpi) 換算
低密度(ldpi) 240 x 320 120 1dp = 0.75px
中密度(mdpi) 320 x 480 160 1dp=1px
高密度(hdpi) 480 x 800 240 1dp=1.5px
超高密度(xhdpi) 720 x 1280 320 1dp=2px
超超高密度(xxhdpi) 1080 x 1920 480 1dp=3px

6、獨(dú)立比例像素(sp):

  • 含義:scale-independent pixel,叫sp或sip
  • 單位:sp,字體大小專(zhuān)用單位
    Android開(kāi)發(fā)時(shí)用此單位設(shè)置文字大小,可根據(jù)字體大小首選項(xiàng)進(jìn)行縮放;
    推薦使用12sp、14sp、18sp、22sp作為字體大小,不推薦使用奇數(shù)和小數(shù),容易造成精度丟失,12sp以下字體太小。

7、sp 與 dp 的區(qū)別:

  • dp只跟屏幕的像素密度有關(guān);
  • sp和dp很類(lèi)似但唯一的區(qū)別是,Android系統(tǒng)允許用戶(hù)自定義文字尺寸大?。ㄐ ⒄?、大、超大等等),當(dāng)文字尺寸是“正?!睍r(shí)1sp=1dp=0.00625英寸,而當(dāng)文字尺寸是“大”或“超大”時(shí),1sp>1dp=0.00625英寸。類(lèi)似我們?cè)趙indows里調(diào)整字體尺寸以后的效果——窗口大小不變,只有文字大小改變。

追到android源碼,發(fā)現(xiàn)系統(tǒng)內(nèi)部用applyDimension()
(路徑:android.util.TypedValue.applyDimension())將所有單位都轉(zhuǎn)換成px 再處理:

   /**
     * Converts an unpacked complex data value holding a dimension to its final floating 
     * point value. The two parameters <var>unit</var> and <var>value</var>
     * are as in {@link #TYPE_DIMENSION}.
     *  
     * @param unit The unit to convert from.
     * @param value The value to apply the unit to.
     * @param metrics Current display metrics to use in the conversion -- 
     *                supplies display density and scaling information.
     * 
     * @return The complex floating point value multiplied by the appropriate 
     * metrics depending on its unit. 
     */
    public static float applyDimension(int unit, float value,
                                       DisplayMetrics metrics)
    {
        switch (unit) {
        case COMPLEX_UNIT_PX:
            return value;
        case COMPLEX_UNIT_DIP:
            return value * metrics.density;
        case COMPLEX_UNIT_SP:
            return value * metrics.scaledDensity;
        case COMPLEX_UNIT_PT:
            return value * metrics.xdpi * (1.0f/72);
        case COMPLEX_UNIT_IN:
            return value * metrics.xdpi;
        case COMPLEX_UNIT_MM:
            return value * metrics.xdpi * (1.0f/25.4f);
        }
        return 0;
    }

      可以發(fā)現(xiàn)dp和sp的區(qū)別在于density和scaledDensity兩個(gè)值上;

    /**
     * The logical density of the display.  This is a scaling factor for the
     * Density Independent Pixel unit, where one DIP is one pixel on an
     * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), 
     * providing the baseline of the system's display. Thus on a 160dpi screen 
     * this density value will be 1; on a 120 dpi screen it would be .75; etc.
     *  
     * <p>This value does not exactly follow the real screen size (as given by 
     * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
     * the overall UI in steps based on gross changes in the display dpi.  For 
     * example, a 240x320 screen will have a density of 1 even if its width is 
     * 1.8", 1.3", etc. However, if the screen resolution is increased to 
     * 320x480 but the screen size remained 1.5"x2" then the density would be 
     * increased (probably to 1.5).
     *
     * @see #DENSITY_DEFAULT
     */
    public float density;

    /**
     * A scaling factor for fonts displayed on the display.  This is the same
     * as {@link #density}, except that it may be adjusted in smaller
     * increments at runtime based on a user preference for the font size.
     */
    public float scaledDensity;

三、適配方案

屏幕適配問(wèn)題的本質(zhì)是使得布局、布局組件在Android不同尺寸、不同分辨率的手機(jī)上具備相同的顯示效果,下面我將分幾個(gè)方面來(lái)談?wù)勅绾稳ミm配。

3.1 關(guān)于布局組件的適配:

  • 3.1.1 使用密度無(wú)關(guān)像素指定尺寸
    由于各種屏幕的像素密度都有所不同,因此相同數(shù)量的像素在不同設(shè)備上的實(shí)際大小也會(huì)有所差異,這樣使用像素(px)定義布局尺寸就會(huì)產(chǎn)生問(wèn)題。
    因此,請(qǐng)務(wù)必使用密度無(wú)關(guān)像素 dp 或獨(dú)立比例像素 sp 單位指定尺寸。

備注:在生產(chǎn)過(guò)程中,廠家不會(huì)完全按照屏幕密度標(biāo)準(zhǔn)去生產(chǎn)Android設(shè)備,會(huì)在Google的標(biāo)準(zhǔn)周?chē)?dòng)變化,或是偏離Google的屏幕密度標(biāo)準(zhǔn)比較大,再加上理論計(jì)算(開(kāi)方)造成的誤差,實(shí)際上使用dp作為單位是不能完完全全的完成適配操作;

  • 3.1.2 使用相對(duì)布局或線性布局,不要使用絕對(duì)布局
    對(duì)于線性布局(Linearlayout)、相對(duì)布局(RelativeLayout)、幀布局(FrameLayout)、絕對(duì)布局(AbsoluteLayout)以及新增的加強(qiáng)版幀布局(CoordinatorLayout)需要根據(jù)需求進(jìn)行選擇,沒(méi)有絕對(duì)而言。
    但因?yàn)镽elativeLayout講究的是相對(duì)位置,即使屏幕的大小改變,視圖之前的相對(duì)位置都不會(huì)變化,與屏幕大小無(wú)關(guān),靈活性很強(qiáng),而LinearLayout法準(zhǔn)確地控制子視圖之間的位置關(guān)系,只能簡(jiǎn)單的一個(gè)挨著一個(gè)地排列,所以,對(duì)于屏幕適配來(lái)說(shuō),使用相對(duì)布局(RelativeLayout)將會(huì)是更好的解決方案,至于絕對(duì)布局由于適配性極差,所以極少使用。

  • 3.1.3 使用wrap_content、match_parent、權(quán)重
    使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬編碼的尺寸,系統(tǒng)會(huì)自動(dòng)計(jì)算相應(yīng)的數(shù)值,視圖就會(huì)相應(yīng)地使用自身所需的空間或填滿(mǎn)可用空間,讓布局正確適應(yīng)各種屏幕尺寸和屏幕方向,組件的權(quán)重比同理。

  • 3.1.4 使用minWidth、minHeight、lines等屬性
    很多時(shí)候我們顯示的數(shù)據(jù)都是由后臺(tái)返回的,再由我們加工處理后去適配我們的組件,這些數(shù)據(jù)的長(zhǎng)度我們是無(wú)法確定的,而正常情況下我們構(gòu)思的布局都僅是適用于理想的情況下,為了保證界面的對(duì)齊、數(shù)據(jù)顯示完整等等的原因,我們需要在構(gòu)思布局時(shí)增加對(duì)組件最小寬高度、行數(shù)等屬性的設(shè)置,確保在特殊的數(shù)據(jù)下不會(huì)破壞我們的整體布局。

  • 3.1.5 dimens使用
    組件的長(zhǎng)寬我們可以通過(guò)dimens來(lái)定義,不同的屏幕尺寸可以定義不同的數(shù)值,或者是不同的語(yǔ)言顯示我們也可以定義不同的數(shù)值,因?yàn)榉g后的長(zhǎng)度一般都不會(huì)跟中文的一致。

3.2 關(guān)于布局的適配:

以上幾種方式可以解決屏幕適配性的問(wèn)題,但是那些通過(guò)伸縮控件來(lái)適應(yīng)各種不同屏幕大小的布局,未必就是提供了最好的用戶(hù)體驗(yàn)。你的應(yīng)用程序應(yīng)該不僅僅實(shí)現(xiàn)了可自適應(yīng)的布局,還應(yīng)該提供一些方案根據(jù)屏幕的配置來(lái)加載不同的布局,可以通過(guò)配置限定符(configuration qualifiers)來(lái)實(shí)現(xiàn)。配置限定符允許程序在運(yùn)行時(shí)根據(jù)當(dāng)前設(shè)備的配置自動(dòng)加載合適的資源(比如為不同尺寸屏幕設(shè)計(jì)不同的布局)。

  • 3.2.1 使用Size限定符
    很多應(yīng)用會(huì)在較大的屏幕上實(shí)施“雙面板”模式,即在一個(gè)面板上顯示項(xiàng)目列表,而在另一面板上顯示對(duì)應(yīng)內(nèi)容。平板電腦和電視的屏幕已經(jīng)大到可以同時(shí)容納這兩個(gè)面板了,但手機(jī)屏幕就需要分別顯示。因此,我們可以使用以下文件以便實(shí)施這些布局:
單面板 res/layout/main.xml .jpg
雙面板布局 res/layout-large/main.xml.jpg

請(qǐng)注意第二種布局名稱(chēng)目錄中的 large 限定符。系統(tǒng)會(huì)在屬于較大屏幕(例如 7 英寸或更大的平板電腦)的設(shè)備上選擇此布局。系統(tǒng)會(huì)在較小的屏幕上選擇其他布局(無(wú)限定符)。

  • 3.2.2 最小寬度限定符
    使用Size限定符有一個(gè)問(wèn)題會(huì)讓很多程序員感到頭疼,large到底是指多大呢?很多應(yīng)用程序都希望能夠更自由地為不同屏幕設(shè)備加載不同的布局,不管它們是不是被系統(tǒng)認(rèn)定為”large”。這就是Android為什么在3.2以后引入了”Smallest-width”限定符。

    最小寬度限定符可讓您通過(guò)指定某個(gè)最小寬度(以 dp 為單位)來(lái)定位屏幕。例如,標(biāo)準(zhǔn) 7 英寸平板電腦的最小寬度為 600 dp,因此如果您要在此類(lèi)屏幕上的用戶(hù)界面中使用雙面板(但在較小的屏幕上只顯示列表),您可以使用上文中所述的單面板和雙面板這兩種布局,但您應(yīng)使用 sw600dp 指明雙面板布局僅適用于最小寬度為 600 dp 的屏幕,而不是使用 large 尺寸限定符。
單面板 res/layout/main.xml.jpg
雙面板 res/layout-sw600dp/main.xml.jpg

也就是說(shuō),對(duì)于最小寬度大于等于 600 dp 的設(shè)備,系統(tǒng)會(huì)選擇 layout-sw600dp/main.xml(雙面板)布局,否則系統(tǒng)就會(huì)選擇 layout/main.xml(單面板)布局。

但 Android 版本低于 3.2 的設(shè)備不支持此技術(shù),原因是這些設(shè)備無(wú)法將 sw600dp 識(shí)別為尺寸限定符,因此我們?nèi)孕枋褂?large 限定符。這樣一來(lái),就會(huì)有一個(gè)名稱(chēng)為 res/layout-large/main.xml 的文件(與 res/layout-sw600dp/main.xml 一樣)。但是沒(méi)有太大關(guān)系,我們將馬上學(xué)習(xí)如何避免此類(lèi)布局文件出現(xiàn)的重復(fù)。

  • 3.2.3 使用布局別名
    最小寬度限定符僅適用于 Android 3.2 及更高版本。因此,如果我們?nèi)孕枋褂门c較低版本兼容的概括尺寸范圍(小、正常、大和特大)。例如,如果要將用戶(hù)界面設(shè)計(jì)成在手機(jī)上顯示單面板,但在 7 英寸平板電腦、電視和其他較大的設(shè)備上顯示多面板,那么我們就需要提供以下文件:

    res/layout/main.xml: 單面板布局
    res/layout-large: 多面板布局
    res/layout-sw600dp: 多面板布局

后兩個(gè)文件是相同的,因?yàn)槠渲幸粋€(gè)用于和 Android 3.2 設(shè)備匹配,而另一個(gè)則是為使用較低版本 Android 的平板電腦和電視準(zhǔn)備的。

要避免平板電腦和電視的文件出現(xiàn)重復(fù)(以及由此帶來(lái)的維護(hù)問(wèn)題),您可以使用別名文件。例如,您可以定義以下布局:

  • res/layout/main.xml,單面板布局

  • res/layout/main_twopanes.xml,雙面板布局

然后添加這兩個(gè)文件:

res/values-large/layout.xml:

QQ截圖20151029151423.jpg

res/values-sw600dp/layout.xml:

QQ截圖20151029151436.jpg

后兩個(gè)文件的內(nèi)容相同,但它們并未實(shí)際定義布局。它們只是將 main 設(shè)置成了 main_twopanes 的別名。由于這些文件包含 large 和 sw600dp 選擇器,因此無(wú)論 Android 版本如何,系統(tǒng)都會(huì)將這些文件應(yīng)用到平板電腦和電視上(版本低于 3.2 的平板電腦和電視會(huì)匹配 large,版本高于 3.2 的平板電腦和電視則會(huì)匹配 sw600dp)。

  • 3.2.4 使用屏幕方向限定符
    某些布局會(huì)同時(shí)支持橫向模式和縱向模式,但我們可以通過(guò)調(diào)整優(yōu)化其中大部分布局的效果。在新聞閱讀器示例應(yīng)用中,每種屏幕尺寸和屏幕方向下的布局行為方式如下所示:

    小屏幕,縱向:?jiǎn)蚊姘?,帶徽?biāo)
    小屏幕,橫向:?jiǎn)蚊姘?,帶徽?biāo)
    7 英寸平板電腦,縱向:?jiǎn)蚊姘澹瑤Р僮鳈?br> 7 英寸平板電腦,橫向:雙面板,寬,帶操作欄
    10 英寸平板電腦,縱向:雙面板,窄,帶操作欄
    10 英寸平板電腦,橫向:雙面板,寬,帶操作欄
    電視,橫向:雙面板,寬,帶操作欄

    因此,這些布局中的每一種都定義在了 res/layout/ 目錄下的某個(gè) XML 文件中。為了繼續(xù)將每個(gè)布局分配給各種屏幕配置,該應(yīng)用會(huì)使用布局別名將兩者相匹配:

res/layout/onepane.xml:(單面板)

QQ截圖20151029151534.jpg

res/layout/onepane_with_bar.xml:(單面板帶操作欄)

QQ截圖20151029151558.jpg

res/layout/twopanes.xml:(雙面板,寬布局)

QQ截圖20151029151653.jpg

res/layout/twopanes_narrow.xml:(雙面板,窄布局)

QQ截圖20151029151701.jpg

既然我們已定義了所有可能的布局,那就只需使用配置限定符將正確的布局映射到各種配置即可。

現(xiàn)在只需使用布局別名技術(shù)即可做到這一點(diǎn):

res/values/layouts.xml:

QQ截圖20151029151847.jpg

res/values-sw600dp-land/layouts.xml:

QQ截圖20151029151853.jpg

res/values-sw600dp-port/layouts.xml:

QQ截圖20151029151904.jpg

res/values-large-land/layouts.xml:

QQ截圖20151029151914.jpg

res/values-large-port/layouts.xml:

QQ截圖20151029151920.jpg
  • 3.2.5 多套layout適配
    res/values/layouts.xml:
    res/values-sw600dp-land/layouts.xml:
    res/values-sw600dp-port/layouts.xml:
    res/values-large-land/layouts.xml:
    res/values-large-port/layouts.xml:

3.3 關(guān)于圖片的適配:

  • 3.3.1 LOGO 圖標(biāo)
    建議按官方標(biāo)準(zhǔn)準(zhǔn)備好各個(gè)圖標(biāo);
屏幕密度 對(duì)應(yīng)的圖片大小 圖片資源目錄
120dip 36px * 36px mipmap-ldpi
160dip(基準(zhǔn)) 48px * 48px mipmap或者mipmap-mdpi
240dip(1.5倍) 72px * 72px mipmap-hdpi
320dip (2倍) 96px * 96px mipmap-xhdpi
480dip (3倍) 144px * 144px mipmap-xxhdpi
640dip (4倍) 192px * 192px mipmap-xxxhdpi
  • 3.3.2 普通圖片和圖標(biāo)
    建議安裝官方的密度類(lèi)型進(jìn)行切圖即可,但一般我們只需xxhdpi或xxxhdpi的切圖即可滿(mǎn)足我們的需求;

  • 3.3.3 自動(dòng)拉伸位圖:Nine-Patch的圖片類(lèi)型
    支持不同屏幕大小通常情況下也意味著,你的圖片資源也需要有自適應(yīng)的能力。例如,一個(gè)按鈕的背景圖片必須能夠隨著按鈕大小的改變而改變。
    如果你想使用普通的圖片來(lái)實(shí)現(xiàn)上述功能,你會(huì)發(fā)現(xiàn)這是難以實(shí)現(xiàn)的,因?yàn)檫\(yùn)行時(shí)會(huì)均勻地拉伸或壓縮你的圖片。解決方案是使用nine-patch圖片,它是一種被特殊處理過(guò)的PNG圖片,你可以指定哪些區(qū)域可以拉伸而哪些區(qū)域不可以。

  • 3.3.4 動(dòng)畫(huà)、自定義view、shape
    可以使用代碼進(jìn)行控制和展示多種視圖,如patch動(dòng)畫(huà)替代幀動(dòng)畫(huà)。

  • 3.3.5 ImageView的ScaleType適配

  1. android:scaleType=“center”
    保持原圖的大小,顯示在ImageView的中心。當(dāng)原圖的size大于ImageView的size時(shí),多出來(lái)的部分被截掉。
  2. android:scaleType=“center_inside”
    以原圖正常顯示為目的,如果原圖大小大于ImageView的size,就按照比例縮小原圖的寬高,居中顯示在ImageView中。如果原圖size小于ImageView的size,則不做處理居中顯示圖片。
  3. android:scaleType=“center_crop”
    以原圖填滿(mǎn)ImageView為目的,如果原圖size大于ImageView的size,則與center_inside一樣,按比例縮小,居中顯示在ImageView上。如果原圖size小于ImageView的size,則按比例拉升原圖的寬和高,填充ImageView居中顯示。
  4. android:scaleType=“matrix”
    不改變?cè)瓐D的大小,從ImageView的左上角開(kāi)始繪制,超出部分做剪切處理。
  5. androd:scaleType=“fit_xy”
    把圖片按照指定的大小在ImageView中顯示,拉伸顯示圖片,不保持原比例,填滿(mǎn)ImageView.
  6. android:scaleType=“fit_start”
    把原圖按照比例放大縮小到ImageView的高度,顯示在ImageView的start(前部/上部)。
  7. android:sacleType=“fit_center”
    把原圖按照比例放大縮小到ImageView的高度,顯示在ImageView的center(中部/居中顯示)。
  8. android:scaleType=“fit_end”
    把原圖按照比例放大縮小到ImageView的高度,顯示在ImageVIew的end(后部/尾部/底部)


    image.png

3.4 關(guān)于代碼適配:

在代碼中使用Google提供的API對(duì)設(shè)備的屏幕寬度進(jìn)行測(cè)量,然后按照需求進(jìn)行設(shè)置。

對(duì)于當(dāng)前控件的寬高設(shè)置,需要做的操作是首先要獲取到該控件的父控件,使用父控件對(duì)當(dāng)前控件的寬高進(jìn)行設(shè)置操作!

DisplayMetrics metrics = new DisplayMetrics ();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
手機(jī)對(duì)應(yīng)的寬高:
Constants.screenHeight= metrics.heightDixels;
Constants.screenWidth= metrics.widthDixels;
RelativeLayout.LayoutParams=new RelativeLayout.LayoutParams();

(int)( Constants.screenHeight*0.5+0.5f);
(int)( Constants.screenWidth *0.5+0.5f);

在上面的兩個(gè)計(jì)算操作中最后加上0.5f的作用是:進(jìn)行float強(qiáng)轉(zhuǎn)到int類(lèi)型的時(shí)候會(huì)出現(xiàn)都是精度的問(wèn)題。當(dāng)使用Java代碼進(jìn)行寬高設(shè)置的時(shí)候,假如出現(xiàn)320.2dp這樣的數(shù)據(jù)此時(shí)直接進(jìn)行int得到的值是320;但是假如出現(xiàn)320.7這樣的數(shù)據(jù)的時(shí)候,由于int的計(jì)算規(guī)則,會(huì)直接強(qiáng)轉(zhuǎn)為320,但是從實(shí)際出發(fā),這個(gè)時(shí)候的值取321更為合適。

所以在計(jì)算的最后直接加0.5,這樣一來(lái),320.2+0.5=320.7,進(jìn)行數(shù)據(jù)的強(qiáng)轉(zhuǎn)操作得到的數(shù)據(jù)是320,320.7+0.5=321.2,進(jìn)行數(shù)據(jù)強(qiáng)轉(zhuǎn)操作得到的數(shù)據(jù)是321,這樣一來(lái)得到的數(shù)據(jù)就和實(shí)際預(yù)想的更為接近??!

3.5 關(guān)于接口配合:

本地加載圖片前判斷手機(jī)分辨率或像素密度,向服務(wù)器請(qǐng)求對(duì)應(yīng)級(jí)別圖片。


總結(jié)

經(jīng)過(guò)上面的介紹,相信大家對(duì)于屏幕的適配都有了一定的了解,但實(shí)際上我們并不會(huì)完全去執(zhí)行上面的全部操作,而是需要根據(jù)我們的項(xiàng)目需求去選擇最合適的方法去適配。例如說(shuō)你的產(chǎn)品是針對(duì)老年人的,你的字體單位是使用sp還是dp呢?又比如說(shuō)RelativeLayout和權(quán)重能較好的解決適配的問(wèn)題,但實(shí)際上它們消耗更多的性能,如何去衡量性能與適配的度呢?
知識(shí)是死的,人是活的,能靈活運(yùn)用相關(guān)知識(shí)方顯真本事。

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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