天天看點

android資源放置相關問題整理

最近進一步看了一些關于drawable和mipmap兩種圖檔檔案夾差別的文章,現将一些小知識點整理在一起,以便以後查閱。

我們知道Android Studio項目當中有drawable和mipmap檔案夾,都是可以用來放圖檔的,那麼他們有什麼差別呢?根據google官方的介紹,google推薦将launcher icon放在mipmap目錄中,其他的圖檔都還是應該放在drawable目錄下面的。注意,mipmap對圖檔進行了很好的優化,隻是針對launcher icon的。

這是我在這之前對于這兩種檔案夾不同掌握的知識點,下面再補充一些自己了解到的。

1、每種密度下的icon應該設計成什麼尺寸其實Android也是給出了最佳建議,icon的尺寸最好不要随意設計,因為過低的分辨率會造成圖示模糊,而過高的分辨率隻會徒增APK大小,建議尺寸如下表所示:

android資源放置相關問題整理

2、drawable和mipmap有什麼差別呢?

The mipmap folders are for placing your app icons in only. Any other drawable assets you use should be placed in the relevant drawable folders as before.

mipmap檔案夾隻放應用圖示。其他需要使用的drawable資源象之前一樣放到對應的drawable檔案夾。

It’s best practice to place your app icons in mipmap- folders (not the drawable- folders) because they are used at resolutions different from the device’s current density.

應用的啟動圖示最好放到mipmap檔案夾(不是drawable檔案夾),因為它們用在不同分辨率的裝置上。

Note: You should place all launcher icons in the res/mipmap-[density]/ folders, rather than drawable/ folders to ensure launcher apps use the best resolution icon.

注意:你應當将雖有啟動圖示放到res/mipmap-[density]/檔案夾中,而不是drawable/檔案夾,來確定啟動圖檔使用最好的分辨率圖示。

mipmap檔案夾隻是用來放置應用程式的icon的,僅此而已,兩者并沒有什麼差別,但是用mipmap系統會在縮放上提供一定的性能優化。此外,平常我們都是把應用程式的icon圖示和普通的圖檔資源一起放到drawable檔案夾下的,這樣看上去就會比較雜亂,有的時候想從一堆的圖檔資源裡面找icon半天也找不到,而檔案一多也就容易出現漏放的情況,但恰恰Android是極度建議我們在每一種分辨率的檔案夾下面都放一個相應尺寸的icon的,是以将它們獨立出來專門放到mimap檔案夾當中就很好地解決了這個問題。

2、圖檔目錄有mdpi,hdip,xhdpi,xxhdpi,xxxhdpi,那麼我怎麼知道某個特定的手機的圖檔應該放在哪個目錄下面呢?首先,我們要擷取到我們螢幕的dpi的值,方法如下:

float xdpi = getResources().getDisplayMetrics().xdpi;
float ydpi = getResources().getDisplayMetrics().ydpi;
           

好,加入現在我計算出來的這兩個值大約是在400左右的話,我們在參考一下如下的一個表格:

android資源放置相關問題整理

從表中可以看出,400dpi是處于320dpi到480dpi之間的,是以屬于xxhdpi的範圍,是以針對這手機的圖檔就應當放在xxhdpi裡面。

3、drawable檔案夾不同分辨率的圖檔目錄這麼多, 那麼android找圖檔的順序又是怎麼樣的呢?

當我們使用資源id來去引用一張圖檔時,Android會使用一些規則來去幫我們比對最适合的圖檔。什麼叫最适合的圖檔?比如我的手機螢幕密度是xxhdpi,那麼drawable-xxhdpi檔案夾下的圖檔就是最适合的圖檔。是以,當我引用android_logo這張圖時,如果drawable-xxhdpi檔案夾下有這張圖就會優先被使用,在這種情況下,圖檔是不會被縮放的。但是,如果drawable-xxhdpi檔案夾下沒有這張圖時, 系統就會自動去其它檔案夾下找這張圖了,優先會去更高密度的檔案夾下找這張圖檔,我們目前的場景就是drawable-xxxhdpi檔案夾,然後發現這裡也沒有android_logo這張圖,接下來會嘗試再找更高密度的檔案夾,發現沒有更高密度的了,這個時候會去drawable-nodpi檔案夾找這張圖,發現也沒有,那麼就會去更低密度的檔案夾下面找,依次是drawable-xhdpi -> drawable-hdpi -> drawable-mdpi -> drawable-ldpi。

4、同樣的一張圖檔放在drawable的不同分辨率目錄下面的話,在手機上顯示的時候會有放大或者縮小的情況。

這是什麼意思呢?舉個例子來說,加入我的手機的dpi是屬于xxhdpi,那麼我在使用圖檔的時候,圖檔都應該放置在xxhdpi目錄下面。我們定義一個ImageView,在ImageView控件中指定加載dog.png這張圖,并把ImageView控件的寬高都設定成wrap_content,這樣圖檔有多大,我們的控件就會有多大,圖檔占整個螢幕的大小可以用圖檔寬高的分辨率除以分辨率的寬高計算出來。

當你将将dog.png這張圖依次移動(注意是移動而不是複制)到drawable-xhdpi和drawable-hdpi檔案夾下你會發現圖檔被依次放大,占據螢幕的比例也越大。

當了解到了android尋找drawable目錄規則後,我們就可以對這個現象做一個解釋:

  • 當我們将圖檔從xxhdpi移動到hdpi下面後,Android依次取xxxhdip和xhdpi下面照圖檔,發現都沒有找到,最終在drawable-hdpi檔案夾下面找到dog.png這張圖了,但是系統會認為你這張圖是專門為低密度的裝置所設計的,如果直接将這張圖在目前的高密度裝置上使用就有可能會出現像素過低的情況,于是系統自動幫我們做了這樣一個放大操作。
  • 同理,如果系統是在drawable-xxxhdpi檔案夾下面找到這張圖的話,它會認為這張圖是為更高密度的裝置所設計的,如果直接将這張圖在目前裝置上使用就有可能會出現像素過高的情況,于是會自動幫我們做一個縮小的操作。

5、drawable-nodpi這個檔案夾是幹嘛的?

這個檔案夾是一個密度無關的檔案夾,放在這裡的圖檔系統就不會對它進行自動縮放,原圖檔是多大就會實際展示多大。但是要注意一個加載的順序,drawable-nodpi檔案夾是在比對密度檔案夾和更高密度檔案夾都找不到的情況下才會去這裡查找圖檔的,是以放在drawable-nodpi檔案夾裡的圖檔通常情況下不建議再放到别的檔案夾裡面,具體的可參考第3條當中的圖檔查找順序。

6、将同一個圖檔放置在drawable不同分辨率目錄下的縮放倍數是怎麼确定的呢?

android資源放置相關問題整理

看上圖先說結論:可以看到,每一種密度的dpi範圍都有一個最大值,這個最大值之間的比例就是圖檔會被系統自動放大的比例。

舉例來說,mdpi密度的最高dpi值是160,而xxhdpi密度的最高dpi值是480,是以是一個3倍的關系,那麼我們就可以猜測,放到drawable-mdpi檔案夾下的圖檔在xxhdpi密度的裝置上顯示會被放大3倍。對應到android_logo這張圖,原始像素是270480,放大3倍之後就應該是8101440像素。

同理,将圖檔移動到drawable-xxxhdpi目錄下。xxxhdpi密度的最高dpi值是640,480是它的0.75倍,那麼我們就可以猜測,放到drawable-xxxdpi檔案夾下的圖檔在xxhdpi密度的裝置上顯示會被縮小至0.75倍。270480的0.75倍應該是202.5360,由于像素不支援小數點,那麼四舍五入就應該是203*360像素。

7、如果在平常開發過程當中開發隻提供了一套圖,那麼我們應該放在哪個目錄下面呢?

就目前來講,最佳放置圖檔資源的檔案夾就是drawable-xxhdpi。那麼有的朋友可能會問了,不是還有更高密度的drawable-xxxhdpi嗎?幹嗎不放在這裡?這是因為,市面上480dpi到640dpi的裝置實在是太少了,如果針對這種級别的螢幕密度來設計圖檔,圖檔在不縮放的情況下本身就已經很大了,基本也起不到節省記憶體開支的作用了。

可以這樣來分析,如果将一張圖檔放在低密度檔案夾下,那麼在高密度裝置上顯示圖檔時就會被自動放大,而如果将一張圖檔放在高密度檔案夾下,那麼在低密度裝置上顯示圖檔時就會被自動縮小。那我們可以通過成本的方式來評估一下,一張原圖檔被縮小了之後顯示其實并沒有什麼副作用,但是一張原圖檔被放大了之後顯示就意味着要占用更多的記憶體了。因為圖檔被放大了,像素點也就變多了,而每個像素點都是要占用記憶體的。

8、在分析的過程中我們提到了同一張圖檔放在不同的檔案夾下面會占用不同的記憶體,這個我們怎麼檢視和驗證呢?

我們可以通過Android Device Monitor來檢視,如下

android資源放置相關問題整理
android資源放置相關問題整理