2014年8月27日 星期三

【Java】interface內的static參數(型別為物件,而不是基本數值型別)

挺奇妙的...

在interface內的參數會被強制宣告為final型態,因此boolean/byte/short/int/char/long/float/double/String這些基本型態的參數一旦寫在裡面,就會被「鎖死」不能再進行修改。

但如果這個參數直接是個類別(A)的實作物件(A),雖然不能修改物件(A)、不能重新宣告或指定新的物件(A),但物件(A)內的參數是可以修改的。

最明顯的例子就是就是宣告ArrayList<T>。

實作這個介面的物件依舊可以動態的、彈性的增減ArrayList<T>的內容。



更奇妙的是可以將這個ArrayList宣告為static屬性。

在多個不同(幾乎沒有相似性)的類別中實作帶ArrayList的介面後,修改、增加ArrayList的內容,然後看看內容組成,(只要看數量就夠了,)會發現ArrayList確實只被產生一次。(它是個綁在介面下的static參數,而不是綁在類別中。)



Android中,Service和Activity的關係一直困擾著我的地方是:Activity要如何對Service內的參數做出修正?或引用Service的屬性和函數?

直接掛上ServiceConnection當然是必要動作,但如果是Activity下所屬的Dialog呢?或是設計者將功能獨立成一個物件,為了能夠在多個Activity中使用,所以傳入參數只使用的基本Context?(好爛的例子......但大家應該懂我真正想表達的,其實就是一個問題:「萬一真的不行,萬一真的有必要另闢途徑,萬一我懶到不想這麼做、專案已經複雜到新增一個傳遞參數大家就會因為要修改舊程式碼而爆炸........有沒有別的選擇?」)

將參數打包成一個物件,然後用interface(I)包裝起來再丟給Service去實作/擴充...這樣一來凡是實作/擴充這個interface(I)的類別都可以享有Service下的參數讀取、甚至修改的權限。



我馬上想到的第一個想法就是設計一個ArrayList<Runnable>,任何被丟進去的Runnable都會被Service執行......當然要做基本的數量控制!......這樣就有簡單的「任務控制器」了。.......這概念大家都稱為「任務控制器」吧?

2014年8月22日 星期五

Android的LayoutInflater真是博大精深啊!!!

public View inflate(int resource, ViewGroup root)

這個Inflater裡的函數非常有趣!

「ViewGroup root」帶Null或帶參數...對「int resource」解析的結果會完全不同!



剛剛同事花了半天才發現如果帶「ViewGroup root」,其實回傳的是這個「ViewGroup root」。

一般情況下這沒什麼,但如果「int resource」最外層的ViewGroup是個設計者自行設計的Layout類別,結果Inflater會忽略這個類別,然後只把「int resource」內的ChildView解析出來、加入「ViewGroup root」中。



會不會有點繞口?



詳細一點說明,如果設計者自行設計了一個LinearLayoutA,並且將它用在XML中,而且是包在檔案最外層。

如果帶了個「ViewGroup root」給Inflater,則Inflater會跳過這個LinearLayoutA的XML不去解析。



如果真是這樣,可以做個實驗.......

XML檔最外層是個FrameLayout,但「ViewGroup root」卻是個LinearLayout。

則用一個「FrameLayout frameLayout」參數去接收Inflater的回傳時,肯定會出錯............



等等做實驗!



(十五分鐘後........)

沒錯!實驗結果完全如此!

2014年8月18日 星期一

【Android】決定Dialog的大小和位置

今天的工作內容是「設計一個Dialog,它彈出的位置會隨著呼叫它的Button位置不同,而跟著不同,例如按鈕如果在整個螢幕偏右側,則視窗要在左側,反之則是在右側。」

問題最後算是初步解決了。以下是心得。



簡單來說,先獲得Dialog下的Window物件,然後再用Window物件產生WindowManager。

([Dialog物件].getWindow()可以獲得Window物件。[Window物件].getWindowManager可以獲得.......別問我怎麼獲得Dialog物件!拒絕回答!)

有了WindowManager,就可以進一步獲得這個Dialog的LayoutParams。

(這個LayoutParams可以說是Dialog的LayoutParams嗎?...這個Params的物件路徑明明白白是歸屬在WindowManager下,所以它到底是.........一點都不重要!)



一般的View元件在有LayoutParams後,決定View的大小位置,就不是什麼難事了!

但.........

不管設了什麼值給這個Params,一旦Dialog執行了show()之後,什麼都有可能亂掉!

例如我碰到的情況是「系統會將寬度強制設回-2」。

(系統會強制用預設的-1/-2覆蓋掉我們給予的值!──似乎不是所有人都會有這個困擾!為何只有某些人會碰到、或基本的程序會節外生枝,........抱歉!還在研究中。)

解決方法在於不使用LayoutParams設定位置與大小,而是使用WindowManager的setLayout(int wid, int height)。

(能不能用同樣的方法指定位置?......晚點試驗一下。)