Android中的不同drawable資料夾所帶來的思考
今天模擬手Q的傳送圖片介面做一個toolBar,佈局如下:
<RelativeLayout android:id="@+id/tool_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/photo_select_bottom_bg" android:layout_alignParentBottom="true" > <Button android:id="@+id/preview_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:text="@string/preview" android:textColor="@color/photopreview_btn_text" android:textSize="14dp" android:paddingLeft="15dp" android:paddingRight="15dp" android:background="@drawable/photopreview_bottom_left_btn_selector" /> <Button android:id="@+id/magic_stick" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_centerVertical="true" android:background="@drawable/pic_icon_edit" /> <Button android:id="@+id/send_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="15dp" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:text="@string/photo_send" android:textColor="@color/photopreview_btn_text" android:textSize="14dp" android:paddingLeft="15dp" android:paddingRight="15dp" android:background="@drawable/photo_select_preview_btn" /> </RelativeLayout>
所有的元素都設定了一個backgroundDrawable,但是執行後得出的介面非常奇怪,
仔細檢查了各項設定引數,均正常,無奈之下各種求助google,度娘,終於解決,現記錄筆記如下:
相關知識
- dip
device independent pixels(裝置獨立畫素),與螢幕密度無關的畫素,這是一個基於螢幕物理的抽象單位。密度可以理解為每英寸所包含的畫素個數,而1dp實際上相當於160dpi(即密度)上的一個點,也就是說,當密度為160時,1dp和1px是等價的。由於android手機的解析度千差萬別,為了讓同一個高度/寬度值在不同解析度的手機上看上去一致,android官方推出了dip的概念。
- dip和px之間的區別和聯絡
dp和px的轉換公式為px=dip*(density/160)
。px就是畫素,打個比方,要畫一條240px的橫線,在480寬的螢幕上看是1半屏款,而在320寬的螢幕上看是2/3(同一個尺寸的螢幕)。而畫一條160dip的橫線,無論在320還是480寬的螢幕上,長度都是一樣的。
- 關於density
上面給出了dip和px之間的轉化公式,其中涉及到了density,注意,這裡的density並非裝置實際的density,而是歸一化後的density。google將所有的裝置分為四種120(low),160(medium),240(high),320(xhigh)。可以使用getResources().getDisplayMetrics().densityDpi
得出結論
根據上面的知識,終於發現了問題所在,我的手機螢幕解析度是240,因此,圖片檔案應該放在drawable-xhdpi下,但是我卻錯誤的將檔案放在了drawable-mdpi,這裡又涉及到了幾個問題,當資原始檔放在了錯誤的資料夾下,會造成什麼樣的影響呢,這麼多資原始檔夾,系統到底是按照什麼順序來載入呢?通過各種資料查詢加上試驗,終於得出結論如下:
-
當圖片資源放在了錯誤的資原始檔夾下時,圖片會根據相應dpi做縮放,拿本例來說,圖片原始大小高度95,當將其放在了drawable-mdpi下時,會通過下列公式計算出大致新的高度
95*(240/160) = 142
,等於說是在縱向拉伸了圖片,這就是為什麼我們在上圖中看到的元素都大了一號,其實是被背景圖給撐大的。 -
載入順序。如果我在drawable-(xdpi,hdpi,mdpi,ldpi)以及drawable這幾個資料夾下放置同一個圖片,那麼系統是按照什麼順序來載入的呢。其實它會先到對應dpi的資料夾下找,找不到就會往比自己高的dpi資料夾下找,然後才會往比自己低的dpi資料夾下找。
至此,問題解決,正常介面: