Friday, May 27, 2011

[Android]Android Drawable物件與螢幕解析度之不思議

用了將近一個月的時間獨自開發完成2011 COMPUTEX TAIPEI application(其中的5%感謝同事的大力幫忙),此次的開發經驗與先前的經驗比較起來,圖形的處理是最大的困難點。


以前開發web的時候,物件的使用幾乎都是著重在與資料庫的連結,然而開發Android的軟體卻不然,物件的使用大部分都是在處理UI(user interface)。如果只是讓使用者單純的點擊buttom、文字、圖形,還算好處理,但是要如何將圖片放大、縮小、位移......等,是以前開發時從來沒有過的經驗。這次軟體開發的經驗就讓我吃足了苦頭,我花了相當多的時間去了解螢幕要如何判斷使用者的手勢(例如:第一指點擊、第一指放開、第二指點擊、第二指放開、拖曳、兩隻手指頭移動),先了解使用者的手勢之後才有辦法判斷要如何將圖片放大縮小或是拖曳,而Android在處理圖片時會用到Drawable、Metrix、Bitmap、Cavans等物件,我也花了很多時間了解這幾種物件的方法與特性(雖然還是一知半解....),了解之後才有辦法在繼續處理其他的問題:要如何將螢幕上點擊的位置轉換成圖片上實際的座標並且帶出公司資訊?要如何取得公司的座標之後,在螢幕上標示出公司所在館場的正確位置?(以上兩種是完全不同的計算方式)

這次使用Drawable物件時就發現相當詭異的事情,例如我寫了以下語法將實際的map圖片檔案轉換成Drawable物件:
public Drawable mIcon;//宣告一個Drawable物件
mIcon = context.getResources().getDrawable(R.drawable.MAP);//此物件等於實際map圖檔

圖檔的原始大小為2000x2000解析度,接下來,我又寫了以下語法要取得圖檔的寬度與高度以供我在計算座標時使用:
imageWeight = mIcon.getIntrinsicWidth();
imageHeight = mIcon.getIntrinsicHeight();

.getIntrinsicWidth()在API裡面的解釋為:Return the intrinsic height of the underlying drawable object.所以以常理來想,imageWeight跟imageHeight得到的值都是2000。好玩的事情發生了,我用不同的手機執行相同的語法,得到的值也不一樣。譬如說HTC Desire得到的值為3000,HTC Lengend得到的值為2000。一開始我不知道不同的手機會有這樣的差異性,在計算圖片座標的時候跟鬼打牆一樣,anyway,雖然最後軟體使用上的問題都解決了,但我卻不知道造成此差異性的原因。

更詭異的事情還在後頭。

HTC Desire的解析度為480x800,若放下一張320x320的圖片會發生什麼情況?請大家再用常理的方式想一下,320x320的圖片若置於Desire中,寬度應該是無法被填滿。但是真實的情況是320x320的圖片放置於Desire中,會剛剛好填滿螢幕的寬。而若將相同的圖片放置於320x480解析度的HTC Legend中,也是剛剛好螢幕的寬。

一開始我並沒有注意到這件事情,一直以為自己放入螢幕中的圖片大小是480x480,取得公司的座標後卻一直無法在地圖上標示出正確的位置,我才意識到,手機上顯示的圖片大小是320x320。後來我將公式更改以符合『真正的』螢幕解析度之後,公司的座標才能夠被正確的標示在地圖上。

但是如果換了不同解析度的機器會發生什麼事情呢?我猜假設使用Android3.0的平板電腦,座標位移的狀況應該會相當嚴重。

這次開發軟體的最大心得以及最大的困難點就是不同螢幕的解析度會影響到整個軟體的使用,突然開始想去寫iPhone app了呀!

4 comments:

  1. 不好意思想請問一下,目前正想做一個圖片的多點觸控,可以放大縮小和拖曳圖片;目前的寫法是自己建立一個ImageView,然後用onTouchEvent去判斷手勢,可是為何放大之後移動圖片都會看到黑底,和圖片的框線,我要如何才能限定移動的範圍就是放大的圖片,最小的範圍就是全螢幕勒~麻煩指教了~謝謝!!!

    ReplyDelete
  2. 樓上的應該可以利用事件抓到的座標來做判斷,限制它不要超過螢幕範圍

    ReplyDelete
    Replies
    1. 邏輯的確是這樣的,只是礙於工作上的限制,我不方便在blog上透露太多程式碼,剛好最近又比較忙,一直沒時間將程式碼改寫之後整理上來,之後有機會會將這部分的程式碼整理上來跟大家分享。

      Delete
  3. 我想HTC Desire得到的值為3000,HTC Lengend得到的值為2000
    這應該是每個螢幕上面分辨率的問題

    像是我用SE X10他的螢幕密度是1.5
    所以我之前試過獨一張圖片寬度是400
    在程式運行中把他log出來顯示是600...

    可以參考此篇文章
    http://www.cnblogs.com/wangtianxj/archive/2011/03/18/1988358.html

    ReplyDelete