1. 程式人生 > >Android 螢幕適配解決方案

Android 螢幕適配解決方案

螢幕適配問題的本質

  • 使得“佈局”、“佈局元件”、“圖片資源”、“使用者介面流程”匹配不同的螢幕尺寸
  • 使得“圖片資源”匹配不同的螢幕密度

這裡寫圖片描述

佈局匹配

本質1:使得佈局元素自適應螢幕尺寸

  • 佈局的子控制元件之間使用相對位置的方式排列,因為RelativeLayout講究的是相對位置,即使螢幕的大小改變,檢視之前的相對位置都不會變化,與螢幕大小無關,靈活性很強
  • LinearLayout無法準確地控制子檢視之間的位置關係,只能簡單的一個挨著一個地排列
    所以,對於螢幕適配來說,使用相對佈局(RelativeLayout)將會是更好的解決方案

本質2:根據螢幕的配置來載入相應的UI佈局

應用場景:需要為不同螢幕尺寸的裝置設計不同的佈局

  • 做法:使用限定符
  • 作用:通過配置限定符使得程式在執行時根據當前裝置的配置(螢幕尺寸)自動載入合適的佈局資源

限定符型別

  • 尺寸(size)限定符
  • 最小寬度(Smallest-width)限定符
  • 佈局別名
  • 螢幕方向(Orientation)限定符

尺寸(size)限定符

使用場景:當一款應用顯示的內容較多
1.在平板電腦和電視的螢幕(>7英寸)上:實施“雙面板”模式以同時顯示更多內容
2.在手機較小的螢幕上:使用單面板分別顯示內容

因此,我們可以使用尺寸限定符(layout-large)通過建立一個檔案來完成上述設定:

res/layout-large/main.xml

這種方式只適合Android 3.2版本之前。因為限定符large 沒有一個定量的指標,這便意味著可能沒辦法準確地根據當前裝置的配置(螢幕尺寸)自動載入合適的佈局資源(3.2後不建議使用)

最小寬度(Smallest-width)限定符

在Android 3.2及之後版本,引入了最小寬度(Smallest-width)限定符

  • 定義:通過指定某個最小寬度(以 dp 為單位)來精確定位螢幕,從而載入不同的UI資源
  • 使用場景:

你需要為標準 7 英寸平板電腦匹配雙面板佈局(其最小寬度為 600 dp),在手機(較小的螢幕上)匹配單面板佈局

  • layout-sw xxxdp 即small width的縮寫,其不區分方向,即無論是寬度還是高度,只要大於 xxxdp,就採用次此佈局

解決方案:您可以使用上文中所述的單面板和雙面板這兩種佈局,但您應使用 sw600dp 指明雙面板佈局僅適用於最小寬度為 600 dp 的螢幕。
例子:
適配手機的單面板(預設)佈局: 適用於最小寬度為 600 dp 的螢幕。res/layout/main.xml

<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>

適用於寬度 ≥ 600 dp 的(雙面板佈局)裝置佈局: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>

使用佈局別名

設想這麼一個場景,當你需要同時為Android 3.2版本前和Android 3.2版本後的手機進行螢幕尺寸適配的時候,由於尺寸限定符僅用於Android 3.2版本前,最小寬度限定符僅用於Android 3.2版本後,所以這會帶來一個問題,為了很好地進行螢幕尺寸的適配,你需要同時維護layout-sw600dp和layout-large的兩套main.xml平板佈局,如下

  • 適配手機的單面板(預設)佈局:res/layout/main.xml
  • 適配尺寸>7寸平板的雙面板佈局(Android 3.2前):res/layout-large/main.xml
  • 適配尺寸>7寸平板的雙面板佈局(Android 3.2後)res/layout-sw600dp/main.xml

最後的兩個檔案的xml內容是完全相同的,這會帶來:檔名的重複從而帶來一些列後期維護的問題,於是為了要解決這種重複問題,我們引入了佈局別名

還是上面的例子,你可以定義以下佈局:

  • 適配手機的單面板(預設)佈局:res/layout/main.xml
  • 適配尺寸>7寸平板的雙面板佈局:res/layout/main_twopanes.xml

然後加入以下兩個檔案,以便進行Android 3.2前和Android 3.2後的版本雙面板佈局適配:

1.res/values-large/layout.xml(Android 3.2之前的雙面板佈局)

<resources>
    <item name="main" type="layout">@layout/main_twopanes</item>
</resources>

2.res/values-sw600dp/layout.xml(Android 3.2及之後的雙面板佈局)

<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>

這樣兩個layout.xml都只是引用了@layout/main_twopanes,就避免了重複定義佈局檔案的情況

螢幕方向(Orientation)限定符

使用場景:根據螢幕方向進行佈局的調整

取以下為例子:

  • 小螢幕, 豎屏: 單面板
  • 小螢幕, 橫屏: 單面板
  • 7 英寸平板電腦,縱向:單面板,帶操作欄
  • 7 英寸平板電腦,橫向:雙面板,寬,帶操作欄
  • 10 英寸平板電腦,縱向:雙面板,窄,帶操作欄
  • 10 英寸平板電腦,橫向:雙面板,寬,帶操作欄
  • 電視,橫向:雙面板,寬,帶操作欄

方法是:

  • 先定義類別:單/雙面板、是否帶操作欄、寬/窄

定義在 res/layout/ 目錄下的某個 XML 檔案中

  • 再進行相應的匹配:螢幕尺寸(小屏、7寸、10寸)、方向(橫、縱)

使用佈局別名進行匹配

1.在 res/layout/ 目錄下的 檔案中定義所需要的佈局類別(單/雙面板、是否帶操作欄、寬/窄)

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

<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/onepane_with_bar.xml:(單面板帶操作欄)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  
    <LinearLayout android:layout_width="match_parent"   
                  android:id="@+id/linearLayout1"    
                  android:gravity="center"  
                  android:layout_height="50dp">  
        <ImageView android:id="@+id/imageView1"   
                   android:layout_height="wrap_content"  
                   android:layout_width="wrap_content"  
                   android:src="@drawable/logo"  
                   android:paddingRight="30dp"  
                   android:layout_gravity="left"  
                   android:layout_weight="0" />  
        <View android:layout_height="wrap_content"   
              android:id="@+id/view1"  
              android:layout_width="wrap_content"  
              android:layout_weight="1" />  
        <Button android:id="@+id/categorybutton"  
                android:background="@drawable/button_bg"  
                android:layout_height="match_parent"  
                android:layout_weight="0"  
                android:layout_width="120dp"  
                style="@style/CategoryButtonStyle"/>  
    </LinearLayout>  

    <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/twopanes.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>

res/layout/twopanes_narrow.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="200dp"
              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>

2.使用佈局別名進行相應的匹配(螢幕尺寸(小屏、7寸、10寸)、方向(橫、縱))
res/values/layouts.xml:(預設佈局)

<resources>  
    <item name="main_layout" type="layout">@layout/onepane_with_bar</item>  
    <bool name="has_two_panes">false</bool>  
</resources>

可為resources設定bool,通過獲取其值來動態判斷目前已處在哪個適配佈局

res/values-sw600dp-land/layouts.xml(大屏、橫向、雙面板、寬-Andorid 3.2版本後)

<resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
</resources>

res/values-sw600dp-port/layouts.xml(大屏、縱向、單面板帶操作欄-Andorid 3.2版本後)

<resources>
    <item name="main_layout" type="layout">@layout/onepane</item>
    <bool name="has_two_panes">false</bool>
</resources>

res/values-large-land/layouts.xml(大屏、橫向、雙面板、寬-Andorid 3.2版本前)

<resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
</resources>

res/values-large-port/layouts.xml(大屏、縱向、單面板帶操作欄-Andorid 3.2版本前)

<resources>
    <item name="main_layout" type="layout">@layout/onepane</item>
    <bool name="has_two_panes">false</bool>
</resources>

佈局元件匹配

本質:使得佈局元件自適應螢幕尺寸

  • 做法 使用”wrap_content”、”match_parent”和”weight“來控制檢視元件的寬度和高度

圖片資源匹配

  • 本質:使得圖片資源在不同螢幕密度上顯示相同的畫素效果
  • 提供備用點陣圖(符合螢幕尺寸的圖片資源)
密度型別 縮寫 代表的解析度 螢幕畫素密度 尺寸比例
低密度 LDPI 240x320 120 0.75
中密度 MDPI 320x480 160 1
高密度 HDPI 480x800 240 1.5
超高密度 XHDPI 720x1280 320 2
超超高密度 XXHDPI 1080x1920 480 3
超超超高密度 XXXHDPI 640 4
  • 步驟1:根據以下尺寸範圍針對各密度生成相應的圖片。

比如說,如果我們為 xhdpi 裝置生成了 200x200 px尺寸的圖片,就應該按照相應比例地為 hdpi、mdpi 和 ldpi 裝置分別生成 150x150、100x100 和 75x75

  • 步驟2:將生成的圖片檔案放在 res/ 下的相應子目錄中(mdpi、hdpi、xhdpi、xxhdpi),系統就會根據執行您應用的裝置的螢幕密度自動選擇合適的圖片

那麼,有沒有一種方法能更好地解決圖片資源適配問題:

  • 保證螢幕密度適配
  • 可以最小佔用設計資源
  • 使得apk包不變大(只使用一套解析度的圖片資源)

1. 先來理解下Android 載入資源過程
Android SDK會根據螢幕密度自動選擇對應的資原始檔進行渲染載入(自動渲染)

比如說,SDK檢測到你手機的解析度是320x480(dpi=160),會優先到drawable-mdpi資料夾下找對應的圖片資源;但假設你只在xhpdi資料夾下有對應的圖片資原始檔(mdpi資料夾是空的),那麼SDK會去xhpdi資料夾找到相應的圖片資原始檔,然後將原有大畫素的圖片自動縮放成小畫素的圖片,於是大畫素的圖片照樣可以在小畫素解析度的手機上正常顯示。

所以需要提供一套你需要支援的最大dpi解析度規格的圖片資源,這樣即使使用者的手機解析度很小,這樣圖片縮小依然很清晰。那麼這一套最大dpi解析度規格應該是哪種呢?是現在市面手機解析度最大可達到1080X1920的解析度(dpi=xxdpi=480)嗎?

2. xhdpi應該是首選

  • xhdpi解析度以內的手機需求量最旺盛
  • 節省設計資源&工作量

在現在的App開發中(iOS和Android版本),有些設計師為了保持App不同版本的體驗互動一致,可能會以iPhone手機為基礎進行設計,包括後期的切圖之類的。
設計師們一般都會用最新的iPhone6和iPhone5s(5s和5的尺寸以及解析度都一樣)來做原型設計,所有引數請看下圖

機型 解析度(px) 螢幕尺寸(inch) 系統密度(dpi)
iPhone 5s 640X1164 4 332
iPhone 6 1334x750 4.7 326
iPhone 6 Plus 1080x1920 5 400

iPhone主流的螢幕dpi約等於320, 剛好屬於xhdpi,所以選擇xhdpi作為唯一一套dpi圖片資源,可以讓設計師不用專門為Android端切圖,直接把iPhone的那一套切好的圖片資源放入drawable-xhdpi資料夾裡就好,這樣大大減少的設計師的工作量!

其他

  1. ImageView的ScaleType屬性
    設定不同的ScaleType會得到不同的顯示效果,一般情況下,設定 為centerCrop能獲得較好的適配效果

  2. 有些情況下,我們需要動態的設定控制元件大小或者是位置,比如說popwindow的顯示位置和偏移量等。這時我們可以動態獲取當前的螢幕屬性,然後設定合適的數值

螢幕密度匹配方案

這裡寫圖片描述

  • 本質:使得佈局元件在不同螢幕密度上顯示相同的畫素效果
  • 做法1:使用密度無關畫素 dp

百分比適配方法

  1. 以某一解析度為基準,生成所有解析度對應畫素數列表
  2. 將生成畫素數列表存放在res目錄下對應的values檔案下
  3. 根據UI設計師給出設計圖上的尺寸,找到對應畫素數的單位,然後設定給控制元件即可

相關推薦

Android開發:最全面、最易懂的Android螢幕解決方案

前言 Android的螢幕適配一直以來都在折磨著我們Android開發者,本文將結合: 給你帶來一種全新、全面而邏輯清晰的Android螢幕適配思路,只要你認真閱讀,保證你能解決Android的螢幕適配問題! 目錄 定義 使得某一元

目前Android最全面、最易懂的Android螢幕解決方案

前言 Android的螢幕適配一直以來都在折磨著我們Android開發者,本文將結合: 給你帶來一種全新、全面而邏輯清晰的Android螢幕適配思路,只要你認真閱讀,保證你能解決Android的螢幕適配問題! 目錄 Androi

Android 螢幕解決方案

螢幕適配問題的本質 使得“佈局”、“佈局元件”、“圖片資源”、“使用者介面流程”匹配不同的螢幕尺寸 使得“圖片資源”匹配不同的螢幕密度 佈局匹配 本質1:使得佈局元素自適應螢幕尺寸 佈局的子控制元件之間使用相對位置的方式排列,因為Relat

Android螢幕解決方案

眾所周知,我們編寫的程式要在不同的裝置中執行,使客戶有完美的體驗效果,就需要對不同解析度的裝置作不同的是配方案,接下來以手機和平板為例進行是配方案,以新聞客戶端中新聞閱讀為例 (1)編寫再手機和平板中的不同佈局檔案 手機佈局: <RelativeLayout xmln

android 螢幕--------解決方案

以下是Demo首頁的預覽圖 一、細說layout_weight 目前最為推薦的Android多螢幕自適應解決方案。     該屬性的作用是決定控制元件在其父佈局中的顯示權重,一般用於線性佈局中。其值越小,則對應的layout_width或layout_height的

Android-- UI 佈局,螢幕解析度相容和版本相容,螢幕解決方案

這篇文章主要是對解決螢幕適配問題思路的總結,會比較抽象,以後逐步把每條步驟對應的【案例】總結上去。 A: 拋開【業務需求】,螢幕適配解決方案的本質是:1.動態控制控制元件的尺寸,2.動態控制檢視佈局。 - 1.動態控制控制元件的尺寸:巧妙結合

Android開發一步到位螢幕解決方案

看簡書上和CSDN都沒有一篇特別有針對性的Android螢幕適配解決方案,大部分都是基於官方的基本的,或者挪來挪去的,最近自己剛好處理一個老專案需要適配大小屏,這裡就貼一個自己的螢幕適配解決方案,有問題大家一起溝通。 大家都知道Android螢幕適配是件非常頭

rem動態螢幕解決方案

(function (doc, win) { var docEl = doc.documentElement var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize' var reca

Cocos2d-x 螢幕解決方案

第一,對於螢幕適配問題,首先必須理解幾個基本的概念。  FrameSize:實際上就是裝置的原始解析度,開發環境中可以通過CCEGLView::sharedOpenGLView()->setFrameSize()來設定裝置的解析度大小,當然也可以可以通過CCEGLVi

android螢幕問題分析及各種解決方案優缺點分析

序 從事android開發已有5年之久,專案中遇到的螢幕適配的問題也有n次了,可是有一個很奇怪也很讓人頭疼的現象讓從事多年開發的我很不爽。什麼問題呢,就是“適配虐我千萬遍,我見適配如初見”,真是想說一句fuck,這次我終於堅決的征服掉了她,下面就來具體講解征服她的全過程,一定要

Android 螢幕:最全面的解決方案

螢幕尺寸適配解決方案.png“佈局”匹配本質1:使得佈局元素自適應螢幕尺寸做法使用相對佈局(RelativeLayout),禁用絕對佈局(AbsoluteLayout)開發中,我們使用的佈局一般有:線性佈局(Linearlayout)相對佈局(RelativeLayout)幀佈局(FrameLayout)絕對

Android螢幕方案

目錄介紹 1.螢幕適配定義 2.相關重要的概念 2.1 螢幕尺寸[物理尺寸] 2.2 螢幕解析度[px] 2.3 螢幕畫素密度[dpi] 2.4 dp、dip、dpi、sp、px 2.5 mdpi、hdpi、xdpi、xxdpi 2.6 獲取螢幕解析度[寬

Android 螢幕方案

前言 本文為自身的總結與結合其他文章引用而成,分別為: wangwangli6: Android開發:最全面、最易懂的Android螢幕適配解決方案 https://blog.csdn.net/wangwangli6/article/details/6

Android 螢幕方案,自動生成不同解析度的值

1、概述 大家在Android開發時,肯定會覺得螢幕適配是個尤其痛苦的事,各種螢幕尺寸適配起來蛋疼無比。如果我們換個角度我們看下這個問題,不知道大家有沒有了解過web前端開發,或者說大家對於網頁都不陌生吧,其實適配的問題在web頁面的設計中理論上也存在,為什麼這麼說呢

Android Camera多螢幕解決預覽照片拉伸

通常,拍照預覽頁面的照片拉伸主要與下面兩個因素有關: 1.     Surfaceview的大小 2.     Camera中的Preview的大小 如下圖:     圖中preview顯示的是手機支援的預覽尺寸,picture顯示的是手機支援設定圖片尺寸,screen顯示

Android螢幕框架-(今日頭條終極方案)

在Android開發中,螢幕適配是一個非常頭痛的問題,因而為了去進行螢幕適配,作為

移動端頁面解決方案

ems 基本上 min win 定位 劃分 單位 scrip 一個 一、流體布局 所謂的流體布局,就是用百分比來定義寬度,最外層容器的寬度設置為100%,就可以適配不同的屏幕,子元素按照比例來設置百分比,子元素整體的百分比之和就是100%,但是如果有子元素設置了邊框,或者p

Android 開發:(九)Android螢幕經驗談

1.名詞解釋 螢幕尺寸: 也就是我們平時所說的某某手機是幾寸屏, 比如HTC one V這款手機是3.7寸的, 這裡的寸說的是英寸(inch),國際上習慣使用的單位,1inch = 2.54cm,3.7寸指的是螢幕的對角線的長度。 螢幕解析度:

Android 螢幕之 dimens

相信做手機端的 App 的小夥伴,只要是產品稍微大一點,就會面臨螢幕適配的問題,對於適配這個問題,網上眾說紛紜,以前雖然有零零散散的看過,但是沒有實踐過,也是在最近遇到這個需求的情況下才研究了一下,現在做個記錄。 1 參考連結 http://blog.csdn.net/qq_341

Android螢幕詳解

本篇文章將解釋什麼是螢幕適配,為什麼要螢幕適配,螢幕適配的本質,和如何解決螢幕適配上的問題。(小白也能看懂哦) 什麼是螢幕適配?     螢幕適配就是讓某一個元素或者是APP中的UI介面在不同解析度、不同尺寸的螢幕上展示出同樣的顯示效果,這就是螢幕適配。 為什麼要