Adnroid應(yīng)用屏幕適配

問題

Android 設(shè)備各種屏幕尺寸和形狀,如何做好適配?

你還在為開發(fā)中頻繁切換環(huán)境打包而煩惱嗎?快來試試 Environment Switcher 吧!使用它可以在app運(yùn)行時一鍵切換環(huán)境,而且還支持其他貼心小功能,有了它媽媽再也不用擔(dān)心頻繁環(huán)境切換了。https://github.com/CodeXiaoMai/EnvironmentSwitcher

解決思路和辦法

  • Android 系統(tǒng)定義了兩種常規(guī)屬性對設(shè)備屏幕進(jìn)行分類:大小和密度。
  • 為了優(yōu)化應(yīng)用程序的外觀,以適應(yīng)不同的屏幕尺寸和密度,可以添加一些替代資源(布局和圖片)。

因此對不同屏幕尺寸、形狀以及密度的適配,其實(shí)就是對布局和圖片的適配。

布局適配

要優(yōu)化不同屏幕尺寸的用戶體驗(yàn),應(yīng)該為要支持的每個屏幕尺寸創(chuàng)建一個獨(dú)特的布局XML文件。每個布局應(yīng)該保存到相應(yīng)的資源目錄中,命名為 - <screen_size>后綴。

Android 3.2 之前和之后的方案是不一樣的。

Android 3.2 -

系統(tǒng)定義了四種常用大小:small, normal, large, xlarge

和四種常用密度:low (ldpi), medium (mdpi 默認(rèn)), high (hdpi), extra high (xhdpi)

就像適配不同的語言一樣,要聲明用于不同屏幕的布局和位圖,必須將這些替代資源放在不同的目錄中。

還要注意,屏幕方向(橫向或縱向)也被認(rèn)為是屏幕尺寸的變化,所以許多應(yīng)用程序應(yīng)該修改布局,以優(yōu)化每個方向的用戶體驗(yàn)。

例如,大型屏幕的獨(dú)特布局應(yīng)該保存在 res/layout-large/ 下。

Android會自動縮放布局,以適應(yīng)屏幕。因此,不同屏幕尺寸的布局不需要擔(dān)心UI元素的絕對大小,而需要重點(diǎn)關(guān)注的是影響用戶體驗(yàn)的布局結(jié)構(gòu)(例如相對于兄弟視圖的重要視圖的大小或位置)。

例如,在項(xiàng)目中創(chuàng)建 默認(rèn)布局支持大屏幕 的替代布局。

MyProject/
    res/
        layout/
            main.xml
        layout-large/
            main.xml

如上面代碼所示,文件名必須完全相同,但內(nèi)容不同,才能為相應(yīng)的屏幕尺寸提供優(yōu)化的UI。

系統(tǒng)會根據(jù)運(yùn)行應(yīng)用程序的設(shè)備的屏幕大小從相應(yīng)的布局目錄加載布局文件。有關(guān)Android選擇適當(dāng)資源的更多信息,請參閱“提供資源”指南。

如果應(yīng)用支持橫豎屏切換,還應(yīng)提供橫屏的布局,這里是一個具有用于橫向定向的替代布局的項(xiàng)目

MyProject/
    res/
        layout/
            main.xml
        layout-land/
            main.xml

默認(rèn)情況下,layout/main.xml 文件用于縱向。

如果你想提供一個支持 大屏幕橫屏 的特殊布局,你需要同時使用 largeland 限定詞:

MyProject/
    res/
        layout/              # default (portrait)
            main.xml
        layout-land/         # landscape
            main.xml
        layout-large/        # large (portrait)
            main.xml
        layout-large-land/   # large landscape
            main.xml

Android 3.2 +

在Android 3.2 之前,其中一個困難是“龐大”的屏幕尺寸容器,其中囊括了 Dell Streak、原版 Galaxy Tab 以及常規(guī) 7 英寸平板電腦。 不過,盡管這些設(shè)備都被視為“大”屏設(shè)備,許多應(yīng)用可能仍需要為此類別中的不同設(shè)備(如為 5 英寸和 7 英寸設(shè)備)顯示不同的布局。 正因如此,Android 在 Android 3.2 中引入了“最小寬度”限定符。

最小寬度 限定符允許您將目標(biāo)鎖定在具有特定最小寬度(單位:dp)的屏幕。 例如,典型的 7 英寸平板電腦最小寬度為 600dp,因此,如果您希望您的 UI 在這些屏幕上顯示兩個窗格(但在較小屏幕上顯示單個列表),您同樣可以為單窗格布局和雙窗格布局使用兩種布局,但不使用 large 尺寸限定符,而是使用 sw600dp 為最小寬度是 600dp 的屏幕指定雙窗格布局:

  • res/layout/main.xml,單窗格(默認(rèn))布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>
  • res/layout-sw600dp/main.xml,雙窗格布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="400dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

這意味著,最小寬度大于或等于 600dp 的設(shè)備將選擇 layout-sw600dp/main.xml(雙窗格)布局,而屏幕較小的設(shè)備將選擇 layout/main.xml(單窗格)布局。

不過,這種方法在低于 3.2 版本的設(shè)備上不太奏效,因?yàn)樗鼈儫o法將 sw600dp 識別為尺寸限定符,所以您仍需使用 large 限定符。因此,您應(yīng)該建立一個與 res/layout-sw600dp/main.xml 完全相同的、名為 res/layout-large/main.xml 的文件。下文介紹的技巧可讓您避免因此而產(chǎn)生重復(fù)的布局文件。

使用布局別名

如果您的應(yīng)用的 minSdkVersion 大于等于 3.2,可以跳過此部分。

最小寬度限定符僅在 Android 3.2 及更高版本上提供。因此,您仍應(yīng)使用兼容早期版本的抽象尺寸容器(小、正常、大和超大)。 例如,如果您想讓自己設(shè)計的 UI 在手機(jī)上顯示單窗格 UI,但在 7 英寸平板電腦、TV 及其他大屏設(shè)備上顯示多窗格 UI,則需要提供下列文件:

  • res/layout/main.xml: 單窗格布局
  • res/layout-large: 多窗格布局
  • res/layout-sw600dp: 多窗格布局

后兩個文件雖然名字不同,但內(nèi)容完全相同,因?yàn)槠渲幸粋€將由 Android 3.2 + 設(shè)備匹配,另一個是為了照顧使用早期版本 Android 的平板電腦和 TV 的需要。

為避免為平板電腦和 TV 產(chǎn)生相同的重復(fù)文件(以及由此帶來的維護(hù)難題),您可以使用別名文件。 例如,您可以定義下列布局:

  • res/layout/main.xml,單窗格布局
  • res/layout/main_twopanes.xml,雙窗格布局

并添加以下兩個文件:

  • res/values-large/layout.xml:
<resources>
    <item name="main" type="layout">@layout/main_twopanes</item>
</resources>
  • res/values-sw600dp/layout.xml:
<resources>
    <item name="main" type="layout">@layout/main_twopanes</item>
</resources>

后兩個文件內(nèi)容完全相同,但它們實(shí)際上并未定義布局, 而只是將 main 設(shè)置為 main_twopanes 的別名。由于這些文件具有 large 和 sw600dp 選擇器,因此它們適用于任何 Android 版本的平板電腦和電視(低于 3.2 版本的平板電腦和電視匹配 large,高于 3.2 版本者將匹配 sw600dp)。

創(chuàng)建不同的位圖

我們應(yīng)該始終提供適當(dāng)縮放到每個通用密度設(shè)備的位圖資源:低,中,高和超高密度。這有助于App在所有屏幕密度上實(shí)現(xiàn)良好的圖形質(zhì)量和性能。

要生成這些圖像,應(yīng)該以矢量格式從原始資源開始,并使用以下尺寸比例為每個密度生成圖片:

  • xhdpi: 2.0
  • hdpi: 1.5
  • mdpi: 1.0 (baseline)
  • ldpi: 0.75

例如:如果為xhdpi設(shè)備生成200x200圖片,則應(yīng)為hdpi生成150x150,mdpi為100x100,ldpi 為75x75的的相同資源。

然后,將文件放在適當(dāng)?shù)膁rawable資源目錄中:

MyProject/
    res/
        drawable-xhdpi/
            awesomeimage.png
        drawable-hdpi/
            awesomeimage.png
        drawable-mdpi/
            awesomeimage.png
        drawable-ldpi/
            awesomeimage.png

當(dāng)在代碼中引用@drawable/awesomeimage時,系統(tǒng)會根據(jù)當(dāng)前設(shè)備的屏幕密度選擇適當(dāng)?shù)奈粓D。

低密度(ldpi)資源并不總是必需的。如果提供了hdpi資源時,系統(tǒng)將其縮小一半以適應(yīng)ldpi屏幕。

使用九宮格位圖

支持不同屏幕尺寸通常意味著您的圖像資源也必須能夠適應(yīng)不同的尺寸。 例如,按鈕背景必須能夠適應(yīng)其所應(yīng)用到的任何一種按鈕形狀。

如果您在可能改變尺寸的組件上使用簡單圖像,您很快會發(fā)現(xiàn)效果有些差強(qiáng)人意,因?yàn)檫\(yùn)行組件會均勻地拉伸或縮小您的圖像。 解決方案是使用九宮格位圖,這種特殊格式的 PNG 文件會指示哪些區(qū)域可以拉伸,哪些區(qū)域不可以拉伸。

因此,在設(shè)計將用于尺寸可變組件的位圖時,請一律使用九宮格位圖。

參考文章

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

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

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