【原创】多dpi适配的新姿势
多dpi適配的新姿勢
1. 簡介
? ? ? Android中經常要通過ImageView進行圖片資源顯示。在加載圖片時,首先要考慮的兩個因素就是體驗問題和性能問題。
? ? ? 其中,體驗問題是指圖片顯示的是否正確(例如Universal-Image-Loader在適配Adapter圖片資源時會導致圖片顯示錯位),圖片顯示尺寸是否合適,分辨率是否合適等。本文重點介紹ImageView加載圖片中的顯示問題。
2. 問題
? ? ? 在開發的過程中,一般會將不同分辨率的圖片放置在不同的文件夾中,例如將三種同樣內容不同分辨率的圖片分別放置在drawable-xhdpi,drawable-xxhdpi和drawable-xxxhdpi中。那么,為什么要放置不同分辨率的圖片,只放置一張對圖片的顯示有影響嗎?本文中將對這個問題進行分析。
3. 概念描述
? ? ? 首先,圖片對內存的占用是一個疊加的過程,也就是說圖片資源不是及時釋放的,使用過的圖片在回收過程中可能會有一定程度的延遲。此外,很多時候圖片所依附的Activity是出于當前Activity棧底的狀態,再GC回收過程,這樣的bitmap資源會被認為是活躍狀態的,不會被Android系統回收。
? ? ? 另外一方面,Android中圖片加載到內存中的內存占用跟圖片的實際大小沒有直接的關系,甚至于圖片的實際像素尺寸也沒有直接的關系。
? ? ? 在這里,首先要介紹幾個概念:
- 屏幕尺寸:指屏幕的對角線的長度,單位是英寸,1英寸=2.54厘米;
- 屏幕分辨率:指在橫縱向上的像素點數,單位是px,1px=1個像素點。一般以縱向像素*橫向像素,如1960*1080;
- 屏幕像素密度:是指每英寸上的像素點數,單位是dpi,即"dot per inch"的縮寫。屏幕像素密度與屏幕尺寸和屏幕分辨率有關,在單一變化條件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小;
- dp/dip:Density Independent Pixels, 密度無關像素的縮寫;
- px:像素,物理上的絕對單位
- sp:Scale-Independent Pixels的縮寫
? ? ? 一般而言,會有控件使用dp而文字使用sp的說法,但是也不盡然,sp會隨著系統文字大小進行拉伸,而dp不會,再具體使用過程中還是要根據實際情況進行使用。
?
4. 多dpi適配
? ? ? 圖像資源的多dpi適配,就是要在在不同的dpi文件夾中放置不同尺寸的圖像資源,供設備自動跳轉要顯示的資源。以mdpi為尺寸基準1x,借一張很經典的圖,多dpi適配可以表示如下:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖1. 多dpi資源適配
? ? ? Android系統尋找圖片的步驟是這樣的:
去屏幕密度對應的目錄去找。如果找到就拿來用。
如果沒找到,就去比這個密度高一級的目錄里面去找,如果找到就拿來用。
如果沒找到就繼續往上找。以此類推。
如果到了xxhdpi目錄還沒有找到的話,就會去比自身屏幕密度低一級的目錄去找,如果低一級的目錄>=hdpi,找到了就拿來用。
如果沒找到,就去mdpi目錄去找,如果找到了,就拿來用。
如果沒找到,就去默認的drawble目錄里去找,如果找到了就拿來用。
如果沒找到,再去最低的ldpi目錄里去找。如果找到了,就拿來用。
如果沒找到,那就是沒找到了,圖片無法顯示。(不過一般不會出現這種現象,因為如果每個目錄都沒有這個圖片的話,你是編譯不過的)
? ? ? 如果不是在對應目錄里面找到的圖片資源,要根據實際使用情況,進行顯示,根據顯示模式的不同,主要有以下兩種情況:
(1). MeasureSpec.EXACTLY
? ? ? 這種情況下,圖片的布局規則為match_parent或者是具體大小的數值(如layout_width =60dp, layout_height=60dp),這種情況下,圖片的顯示尺寸是固定的,所以顯示的大小不會因為所在的資源文件夾dpi的不同而有所變化;例如圖片A(尺寸60*60 大小2.02K)分別放置在xxhdpi文件夾和mdpi文件夾(Target Density),尺寸設置為layout_width =60dp, layout_height=60dp,顯示分別如下:
? ? ? ?
? ? ? ? ? ?(a). mdpi文件夾下的顯示 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(b). xxhdpi文件夾下的顯示
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖2. Exactly模式下圖像在不同Target Density下的顯示
(2). MeasureSpec.AT_MOST
? ? ? 這種情況下,圖片的布局規則為wrap_content。系統會根據圖像內容的實際大小進行顯示。同一張圖片放在不同文件夾顯示大小會有所不同,具體而言,同一張圖像資源放置在mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi(Target Density)里面,顯示的大小比較分別為:2:3:4:6:8。
? ? ? 例如wrap_content布局下,分別將同一張圖像A(尺寸60*60 大小2.02K)放置在xxhdpi和hdpi資源文件夾中,顯示效果如下:
??
? ? ? ? ? ? ? ? ? ? ? ? ? ?(a). hdpi文件夾下的顯示 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (b). xxhdpi文件夾下的顯示
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖3. At Most模式下圖像在不同Target Density下的顯示
? ? ? 但是,在進行多dpi適配的時候,本身放置在mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi里面的圖像資源尺寸比較就是2:3:4:6:8(Source Density),二者完美抵消,所以當前模式下,只放置一張合適尺寸的圖像資源在一個合適的文件夾(Target Density)里面,不會影響不同尺寸設備的顯示效果。
? ? ? 例如wrap_content布局下,分別將分別將同一張圖像A(尺寸60*60 大小2.02K)和圖像B(尺寸30*30 大小2.02K)放置在xxhdpi和hdpi資源文件夾中,顯示效果如下:
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(a).圖像資源A的顯示 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(b). 圖像資源B的顯示
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖4. At Most模式下圖像在等比例Target Density和Source Density下的顯示
5. 總結
? ? ? 在不同顯示模式下,考慮到Exactly模式下圖像資源的顯示尺寸的固定性,以及At Most模式下Source Density和Target Density的抵消性,如果放置一張合適尺寸的圖片資源在合適的文件夾,是可以實現不同設備的多dpi適配(顯示的尺寸正常)。考慮到分辨率和使用率的問題,建議保留xxhdpi文件夾下的圖像資源。
? ? ? 這種方法可以在只保留一種dpi尺寸圖像的情況下,實現對不同機型的圖像顯示適配,從而可以有效的壓縮apk的尺寸。結合之前的一篇博文《加載一張圖片到ImageView到底占據多少內存》,可以發現只保留一份合適dpi的圖像的情況下,運行過程中,加載圖像到內存中的內存占用也是一樣的。也就是說,在功能和性能上講,只保留一種dpi的圖像,是可以完成多dpi適配的。
? ? ?但是,凡事都有但是。這種dpi適配的方式有兩個問題:
? ? ?(1). 只保留一張圖片,在進行多dpi適配的時候,有可能會造成圖像顯示分辨率過低,導致體驗性問題。這種情況,一般會在低dpi圖像(Source Density)到高dpi機型(Target Density)適配的時候會出現;
? ? ?(2). 在進行bitmap圖像尺寸換算的時候,計算過程中,會造成內存和cpu的額外開銷,這在低配機型上,有可能會在頻繁地降采樣過程中,導致OOM。
? ? ?以上兩點要重點關注。
? ? ?當然,如果要是做某款特定機型的預制應用,那么,毫無疑問,直接保留一種dpi的圖片資源。
6. 參考文獻
http://www.cnblogs.com/zhwl/archive/2013/06/12/3132722.html
http://blog.csdn.net/skykingf/article/details/45536143
http://www.itnose.net/detail/6614353.html
轉載于:https://www.cnblogs.com/charles04/p/6914859.html
總結
以上是生活随笔為你收集整理的【原创】多dpi适配的新姿势的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos7 配置虚拟交换机(物理交换
- 下一篇: 一个基于cocos2d-x 3.0和Bo