android多分辨率像素指定

efbb 9年前發布 | 14K 次閱讀 Android Android開發 移動開發

開發手機android應用,必定面臨多屏幕支持問題。你一定希望應用程序能在不同的大小的手機上都能很好的展現漂亮的布局和細膩的圖片。本文將介紹如何做到這一點。

先看看沒有支持多分辨率程序的效果。下面是同一個程序運行在兩個不同規格的屏幕上的截圖。右邊這個似乎不可接受。

  android多分辨率像素指定               android多分辨率像素指定

     圖1:480*800,3.5寸屏                       圖2     480*800,5寸屏

 

 

支持多分辨率后的效果

 

android多分辨率像素指定                     android多分辨率像素指定

    圖3 480*800,3.5寸屏                          圖4  480*800,5寸屏

   

  

   我們先來了解一些屏幕的基本概念:

    物理尺寸: 就是所說的幾寸的屏幕,代表屏幕對角線的長度,比如3.5寸、3.7寸、4寸、7寸等。

    分辨率: 是屏幕總共能顯示的像素數,通常我們都說幾百×幾百,比如240*320,320*480,480*800等

    像素密度(DPI):DPI的全稱是dots per inch,每英寸點數.

    這三個參數,任兩個確定后,第三個量就是確定了。公式為:某邊的分辨率(總像素數)= 該邊物理尺寸(單位是英寸) × 像素密度。

    比如一個3.5寸的屏幕,分辨率為480×800,那么密度為開方(480^2+800^2)/3.5 約等于為194。屏幕大小和屏幕像素密度是可以獨立的,不是說一個5寸屏的密度就一定是hdpi。

 

   手機屏幕分類

   按密度分為:低密度(ldpi),中密度(ndpi),高密度(hdpi),超高密度(xhdpi)。

   按尺寸分為: small, normal, large, and xlarge

   android多分辨率像素指定
                                       圖5

  

   大部分手機集中在normal,hdpi這一欄。可見多屏幕適配的重點在這里。

   android多分辨率像素指定
                圖6

 

    適應多屏幕要分別考慮界面布局和圖片資源兩個方面(一體兩面)。

    布局上不考慮多屏幕尺寸,可能出現控件沒對齊,尺寸超出屏幕外等。

    圖片上不考慮多屏幕密度,可能出現圖片看起來大小不合適,比較模糊等。

    到底要考慮布局,還是考慮圖片,或者兩者同時考慮由應用決定。我個人覺得,一般布局要考慮得多一些。如果應用有很多圖片,而且對現實細膩程度要求很高,才考慮圖片。

    但是,所謂考慮多屏幕適應,并非要為沒每種屏幕大小提供一個布局文件,也并非要為每種屏幕密度提供一套位圖,按大的分類提供就可以了。(如果要那樣做也沒錯,但將付出巨大的維護代價)

    例 如,一般為所有尺寸是normal的屏幕提供一套布局,盡管normal里又分很多種(看 圖 5),但一般android都能很好的適應。也可以為所有密度是hdpi的屏幕提供一套圖片,盡管hdpi也分很多種(看 圖 5),但一般android都能很好的適應。

    另 外一方面,即使按大的分類考慮布局文件,也并非要為每個布局文件都創建多個版本。只有布局文件中用數值定義了控件大小(無論你用的單位是px還是 dip),才需要考慮寫多個布局文件。如果是用fill_parent,wrap-contents等方式則用一個布局文件就可以了,把它放在 layout目錄里。

    根據密度你僅需要提供drawable下的位圖文件,如果你使用Xml來定義shape,colors或者其他drawable的資源,你就應該放到"drawable/"默認目錄下

    注意:實際開發中,為了適合多屏幕,又減少維護量。mdpi,hdpi內一般要放東西, ldpi則可放可不放。當要用到ldpi時,它從hdpi里去取并縮放。效果也不錯。

 

   Android如何選擇適合當前屏幕的資源呢?

    選取規則如下:

   (Drawabe和Drawabe-mdpi等價)

   (Layout和layout-normal等價)

    1.基于當前屏幕的尺寸和密度,系統會在最匹配的的設備配置下的資源目錄尋找。

    2.如果沒有可用的匹配資源,系統會使用默認資源等比放大或縮小以匹配當前屏幕的大小和密度。 這里的默認資源是沒有后綴的。

    例如對于HVGA,large screen,ldpi的一塊屏幕,系統會優先找res/layout-large,res/drawable-ldpi下的資源。如果沒有,就使用res/layout和res/drawable

    3.如果系統想找一個ldpi(低密度)的資源,但找不到。那么系統會等比縮小hdpi的資源,為什么不尋找mdpi呢?因為系統對于hdpi更容易縮放,它的系數為0.5,相比mdpi的0.75來說。0.5的的性價比更高。

簡要的概述下就是如果沒有匹配的系統會使用默認的資源,如果連默認下都沒有放資源,那么系統就沒有資源可用啦。

    但我實際測試有些出入,如果只在drawable-hdpi里放圖片,其它地方都不放,然后用mdpi的手機去測試,按道理它先找drawable,沒找到就沒則了,但圖片在界面上還是顯示了,說明它找到drawable-hdpi里去了,Why?

 

   多屏幕適應黃金法則

    1.XML Layout中最好控件大小最好用Wrap_content, fill_parent。

    2.如果必須使用數字來到定義控件大小,最好用DIP。文字大小用sp

    3.不要用px定義控件,文字大小。

    4.不要用絕對布局

    5.為不同密度手機,提供不同分辨率圖片,如果你發現一套圖片在另外一種密度的手機上表現都還不錯,就不需要為那種密度提供額外的圖片。

    6.用模擬器測試不同分辨率

    7.需要注意的地方, 以上設置適用于android3.2以下的版本。

 

   圖片設計的一些建議

   圖標建議

   android多分辨率像素指定

   其他圖片建議

    先為主流的中精度屏幕(HVGA)設計一套icon,確定圖片的像素尺寸。

    為高精度屏幕將圖片放大到150%,為低精度屏幕將圖片縮小至75%。即L(0.75) - M (1) - L(1.5)

 

 

   開發適應多屏幕應用程序的基本思路

    首先應當明確應用希望支持幾種分辨率設備;并非越多越好。雖然理論上建議大家支持所有的屏幕設備,但這確實比較麻煩而且很容易出錯。我們一般最好把手機和平板分時兩大類來發布2個APK這樣的效果會更好。 

    其 次,需明確哪些資源文件在不同分辨率的設備存在顯示問題。對于顯示有問題的,需要重新準備與相應分辨率設備適配的資源文件和頁面布局文件。并非一來就要把 想支持的各種尺寸和密度的屏幕對應的目錄建立起來. 先按某種尺寸和密度開發。然后在不同的屏幕上測試,只針對有問題的布局文件和圖片提供另外的支持。

對于布局,如果書寫得當,你會發現只需要一個放在layout里布局文件將可以在各種尺寸的屏幕上很好的顯示。如何書寫得當?請看“多屏幕適應黃金法則”

    對于圖片,在不同密度的屏幕上有可能會產生縮放。但如果變形不是很嚴重,也還是可以接受。畢竟用多張圖片會增加apk包的大小。

    總之,盡量用一套布局和圖片去適應多屏幕。實在很難看,才考慮多個布局和圖片。要記住,這些東西越多,維護起來越麻煩。

    我 在實際開發中,一般先按照WVGA標準,480*800,normal screen,240dpi,3.5寸建立一個模擬器。布局文件目錄先只建layout一個,圖片也先放到drawable-hdpi下,然后在上面調試 UI。覺得沒問題了,才建立其他尺寸和密度的模擬器來看效果,只對需要調整的部分重新設計布局文件和圖片,并放到合適的目錄下。

 

布局實例

AndroidManifest.xml中提供新的一個元素<supports-screens>用于支持多屏幕機制。

<supports-screens

          Android:largeScreens="true"   是否支持大屏

          Android:normalScreens="true"  是否支持中屏

          Android:smallScreens="true"   是否支持小屏

          Android:anyDensity="true"     是否支持多種不同密度

/>

 

選定基準測試屏幕,例如在模擬器上設置WVGAnormal screen, hdpi480*8003.5寸為activity編寫布局文件:preview_photo.xml。 因為是中屏,用res/layout目錄就可以了。不要用絕對布局,盡量用fill_parentwrap_contents指定控件和容器大小,實在沒法了,才用dip指定控件大小。

 

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/previewPhotoLayout"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

        android:orientation="vertical"

        android:gravity="center_vertical"

        android:layout_width="fill_parent"   

        android:layout_height="fill_parent"

        >

        <LinearLayout

            android:gravity="center_horizontal"

            android:orientation="horizontal"

            android:layout_width="fill_parent"

            android:layout_height="fill_parent"

            android:layout_marginBottom="5.0dip"                       

            android:layout_weight="1.0"

            >         

            <ImageView

                android:id="@+id/imageView1"

                android:layout_width="400dip"

                android:layout_height="153dip"

                android:layout_weight="1.0"

                android:background="#ffffffff"

                android:src="@drawable/icon"

            />

            <ImageView

                android:id="@+id/imageView2"

                android:layout_width="400dip"

                android:layout_height="153dip"

                android:layout_weight="1.0"

                android:background="#ffffffff"

                android:layout_marginLeft="5.0dip"

                android:src="@drawable/icon"

            />                    

        </LinearLayout>

        <LinearLayout

            android:gravity="center_horizontal"

            android:orientation="horizontal"

            android:layout_width="fill_parent"

            android:layout_height="fill_parent"

            android:layout_weight="1.0"

            >

            <ImageView

                android:id="@+id/imageView3"

                android:layout_width="400dip"

                android:layout_height="153dip"

                android:layout_weight="1.0"

                android:background="#ffffffff"

                android:src="@drawable/icon"

            />

            <ImageView

                android:id="@+id/imageView4"

                android:layout_width="400dip"

                android:layout_height="153dip"

                android:layout_weight="1.0"

                android:background="#ffffffff"

                android:layout_marginLeft="5.0dip"

                android:src="@drawable/icon"

            />              

        </LinearLayout>

    </LinearLayout>

</FrameLayout>

 

  測試,效果如圖

  android多分辨率像素指定

再切換到小屏幕測試,用模擬器創建一塊屏幕QVGAsmall screen, 240*480, 2.8寸,顯示如下,looks good。就不再需要提供layout-small

    android多分辨率像素指定

再切換到大屏幕。用模擬器創建一塊屏幕:WVGAlarge screen, mdpi, 480-800 5

顯示如下, very ugly, 需要新寫一個布局文件。

    android多分辨率像素指定

于是再寫一個布局文件preview_photo.xml放在res/layout-large下:注意僅僅修改了ImageViewandroid:layout_height這個屬性。可見,使用了數字定義控件大小,要增加不少維護工作量。

 

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/previewPhotoLayout"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

        android:orientation="vertical"

        android:gravity="center_vertical"

        android:layout_width="fill_parent"   

        android:layout_height="fill_parent"

        >

        <LinearLayout

            android:gravity="center_horizontal"

            android:orientation="horizontal"

            android:layout_width="fill_parent"

            android:layout_height="fill_parent"

            android:layout_marginBottom="5.0dip"                      

            android:layout_weight="1.0"

            >         

            <ImageView

                android:id="@+id/imageView1"

                android:layout_width="400dip"

                android:layout_height="240dip"

                android:layout_weight="1.0"

                android:background="#ffffffff"

                android:src="@drawable/icon"

            />

            <ImageView

                android:id="@+id/imageView2"

                android:layout_width="400dip"

                android:layout_height="240dip"

                android:layout_weight="1.0"

                android:background="#ffffffff"

                android:layout_marginLeft="5.0dip"

                android:src="@drawable/icon"

            />                    

        </LinearLayout>

        <LinearLayout

            android:gravity="center_horizontal"

            android:orientation="horizontal"

            android:layout_width="fill_parent"

            android:layout_height="fill_parent"

            android:layout_weight="1.0"

            >

            <ImageView

                android:id="@+id/imageView3"

                android:layout_width="400dip"

                android:layout_height="240dip"

                android:layout_weight="1.0"

                android:background="#ffffffff"

                android:src="@drawable/icon"

            />

            <ImageView

                android:id="@+id/imageView4"

                android:layout_width="400dip"

                android:layout_height="240dip"

                android:layout_weight="1.0"

                android:background="#ffffffff"

                android:layout_marginLeft="5.0dip"

                android:src="@drawable/icon"

            />              

        </LinearLayout>

    </LinearLayout>

</FrameLayout>

 本文由用戶 efbb 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!