2008年6月30日 星期一

如何改變 Spinner 的大小?

How to change the height of drop down list for spinner?

為什麼要有個稱呼一致的名字都這麼地困難?就拿寫 GUI 程式時,一定要用到的 GUI Framework 來說,大概只有 button 這個控制元件,名稱還算一致。其他的,可就沒這麼幸運了,毎家都有他自己的叫法。

初時在讀 Android 的文件時,看到 Spinner 這個 widget,還真的丈二金剛摸不著頭緒,一下子還以為這是什麼神奇的元件。仔細一看,哦原來這就是 Windows 中的 DropDownList。在 Qt 的世界裡,這叫做 QComboBox,而 Java 的 AWT 又稱其為 Choice。

看吧!可不可以拜託你們,不要將創意用在這名稱上,真是辛苦了我們這些天生命苦的工程師。寫程式之餘,還要先玩個「對對樂」。

好啦,回歸正傳。在 Android 中,要寫個 Spinner,也不算麻煩,底下是個簡單的範例。

首先,在 layout xml 檔中,加上 Spinner 這個 widget。 程式中的第 12~16 行,告訴你如何將選項字串陣列,加到 Spinner 上。 好了,這執行結果像是這樣。

首先看到的問題,就看我之前寫的 親愛的,我把 AutoCompleteTextView 縮小了 一樣。這 Spinner 的長相,實在是太大了。不過,有看過這篇的你,大概已經猜到解法了。不過這 Spinner 有點特別,他有一個 android.R.layout.simple_spinner_item 外,還有一個 android.R.layout.simple_spinner_dropdown_item。

從名稱看來,simple_spinner_item 應該是用在 Spinner 本身,另一個 simple_spinner_dropdown_item 則是用在 Spinner 的下拉列表中。我們先來改變下拉列表的大小好了。

改法一樣,參考 simple_spinner_dropdown_item.xml 的內容,自己寫個 small_spinner_dropdown_item.xml。

原來的 simple_spinner_dropdown_item.xml 內容如下: 改好後的 small_spinner_dropdown_item.xml 像這樣。第 6,9 行,就是更改的部份。 再將原程式第 14 行中的 android.R.layout.simple_spinner_dropdown_item,換成 R.layout.small_spinner_dropdown_item。
adapter.setDropDownViewResource(R.layout.small_spinner_dropdown_item);
大功告成,這執行結果像是這樣。

等一下,這 Spinner 本身的大小,好像還沒改。

的確是,我原先以為一樣畫葫蘆,將 android.R.layout.simple_spinner_item 改掉,就可以了。可是事情好像沒有那麼地簡單,試了半天,都沒效。只好向高手求助一下,有誰知道答案的,請貢獻一下你的解法。

21 則留言:

Neil 提到...

如果要改Spinner 本身的大小
你應該要對Spinner 的android:layout_height進行更改

samlu 提到...

哎呀,這麼簡單的方法,我都忘了試了。
改 layout_height 成 35sp,的確可以改變這 spinner 本身的大小。
不過,35sp 似乎是最小的高度了。
再改小,右邊的箭頭圖形,好像也不會跟著變小。
謝謝你的解答。

匿名 提到...

你好,我目前正在學習android,沒有java的基礎,
網路上查詢資料時發現了你的blog,
很高興有位高手有這麼容易聯絡的方式^^
我想請問:
假設我今天利用spinner選擇了Taiwan,
而Taiwan代表的是zh,
我不明白的是要如何設定這個zh,
不知道我這樣的問題你是否明白?
麻煩你了,謝謝!
by小祥

samlu 提到...

小祥,
如果你有學過其他物件導向語言,像是 C++,要再學 java ,應該是不難的。告訴你個小秘密,我也是才剛學 java 沒多久。
關於你的問題,我看不太懂。我知道的是,中文語系代碼是 zh (ISO 639),而台灣地區使用的中文是 zh-tw (ISO 639/ISO 3166)。大陸地區用的中文就是 zh-cn。不曉得你拿到這語系代碼後,是要設定到那裡?

匿名 提到...

是這樣的,
假設我利用spinner的項目選擇了台灣,
那麼zh將會被代入xxx[zh-tw],
[]內有可能是大陸的zh-ch、美國的en...等。
在android中,我要使用webview,把變數代入到網址內。
loadurl("http://xxx.xxx-[zh]")
不曉得這樣的說明清楚嗎?
我也相信java是不難的^^!
剛接觸android不久我就愛上了,哈!
操作的豐富性讓我挖不完XD!
謝謝你花時間為我解答問題喔!
by小祥

samlu 提到...

小祥,
你問題的答案應該用 java 中基本的字串相加 (string cascade) 就可以了。例如

var url = "http://xxx-xxx-" + lang + "yyy";

在此的 lang 變數就是 "zh-tw", "zh-cn", or "en"。
這有回答你的問題嗎?

匿名 提到...

嗯!我了解,
假設:
if(String[] COUNTRIES=="Taiwan")
String [] lang = "zh-tw";
...
如果今天我有100個COUNTRIES,不就要寫100個if...??

麻煩你了^^ 讓你花時間講解給我聽。
感謝你XD!
by小祥

samlu 提到...

小祥,
當然不用寫 N 個 if 囉。
通常你會將所有的國家名稱都放在一個 String array 中。你也可以仿此,產生另一個

String[] LANGS = new String[] {"zh-tw", "zh-cn", "en"...}

而這個 LANGS 陣列中的語言剛好是和 COUNTRIES,相對應的。如此一來, 拿spinner 的 getSelectedItemPosition() 值當 LANGS 陣列的索引,就是你要的。

匿名 提到...

謝謝你^^
我了解了!
我google了getSelectedItemPosition()的用法,結果...
private static final String[] coun=new String[]{"繁體中文","簡體中文"};
private static final lang[] coun=new String[]{"zh-tw","zh-cn"};

(spinner使用coun)

int in=spinner.getSelectedItemPosition() ;
setTitle(lang[in]);
...
這樣in可以得到spinner的位置沒錯吧?
雖然剛run時候title有跑出zh-tw,
但是我改變為簡體中文,
title不會變換為zh-cn,
不曉得是哪裡出問題,似乎是程式只跑一次的關係?
by 小祥

samlu 提到...

小祥,
看來你應該沒有對 spinner 設定 setOnItemSelectedListener 。
不要問我這怎麼用喔。

匿名 提到...


搞定了!
剛剛google了一下,總算把這邊的問題都搞定了^^
初學關係,總有好多地方不了解,
但是一步步突破,只有高興跟成就感可以形容!
哈!
非常謝謝你不吝嗇的指教喔!!
還有問題的話可以再來請教你嗎?
by 小祥

diadia 提到...

你好,感謝您的教學,獲益良多,想請教二個問題:
1.有辦法更改 dropdown menu 的高度和寬度嗎? 我試了改 layout_width ,結果是顯示字的地方變小,dropdown menu 還是維持同樣大小。

2.不知道有沒有方法限制 dropdown menu 一頁最多只顯示幾筆資料? 我在網路上查到很多 AutoCompleteTextView dropdown list 的屬性,但是都無法套用到 spinner 上面

感謝你的幫助

samlu 提到...

1. 我不建議你改 dropdown menu 的高度,如果真要改的話,看講義的 "Add Spinner Into Your UI" 那張。將 android.R.layout.simple_spinner_dropdown_item 換成你自己設計的 layout file 即可。
2. 如果是在 AutoCompleteTextView 中,你要自己 implement adapter ,透過 adapter 餵的資料數,就可以控制顯示的資料筆數。

diadia 提到...

Hi Samlu,
謝謝你的回應,我研究了一下,看起來 spinner 的 dropdown menu 是由兩個部分組成,一個是 dropdown menu 的 container(我自已猜的),另一個是 TextView,所有的資料都是顯示在 textview 上面,而修改simple_spinner_dropdown_item 只會修改 textview,所以透過修改 simple_spinner_dropdown_item ,會發現, TextView 的寬或高會改變,但是整個 dropdown menu 還是維持同樣大小。

不知道這樣描述你是否能了解。
非常感謝你熱心的回應,我會再研究看看。

匿名 提到...

你好,请问spinner的选项的宽度可以调整吗??
我试着调整android:layout_width="fill_parent"
但是并没有效果呀!!

匿名 提到...

請問一下,類似透過設定 simple_spinner_dropdown_item 這樣的 layout resource 改變內建元件外觀的作法,有文件可以參考嗎?

譬如在 Spinner 的說明,並未列出 simple_spinner_dropdown_item 的用法。在 Android Developers 文件中搜尋,除了範例程式碼之外,就只找得到 R.layout 的 Constants 定義。

想知道大家都是怎麼知道哪些 resource 可以使用在哪些元件呢?

匿名 提到...

請問你是哪裡人?

匿名 提到...

想請問一下有方式可以抓出系統中package的使用時間嗎
有試著透過PkgUsageStats 從usagestats service抓出來
但是發現我的service要抓出這個時間
假設我今天打開一個app之後就放著不動
usagestats的時間似乎不會增加 要等到有動作才會去更新

除了透過這個方式外 有可以取得精確時間並記錄的方法嗎??

samlu 提到...

有些 app 是透過 parse event log 的方式來追蹤 app 的狀態。

匿名 提到...

我有透過 dumpsys activity中找到想要知道的資訊
但是除了dump到log中去抓出來外 有沒有辦法透過程式直接取得
想取得的資訊在TaskRecord中 但我不知道應該如何import進來使用

匿名 提到...

請問如何調整顯示的筆數:
您說透過 adapter 餵的資料數,就可以控制顯示的資料筆數...
這不太懂.做不出來@@~請問大大要如何做~~

張貼留言