iT邦幫忙

DAY 13
5

Android 學習手札系列 第 13

Day 13 - Android - 限制選擇

  • 分享至 

  • xImage
  •  

昨天認識了輸入框(EditText)的使用,可是在某些時候,好像又不是那麼的方便,以我們使用的例子來說,讓使用者自行輸入要傳遞什麼訊號…好像範圍太大了哦!使用者怎麼會知道有什麼訊號可以輸入呢!所以,我們今天要採介紹大家如何使用下拉選單(Spinner)!
選項對像在下這種懶人型的使用者來說,絕對是一個好介面啊灑花
只要用點的就好了,同時對防呆的機制也一定是正向的加值啊!以我們昨天的例子來說,若是我們沒有限制好暗號的範圍以及規範,傳遞出去後,接收方才發現沒有該代號,不能即時提出支援(有時是找不到bug),那就真的要好好考慮跟各位勇者說「放下屠刀,立地成佛,我們來當個朋友吧」,所以今天的地圖就跟昨天一樣,放上兩個角色:Moogle以及Chocobo,可以直接自行用新增的方式,或是加入既有地圖的方式來增加專案,而專案名稱為:Day13_Spinner。而兩者的外觀如下:

左邊是Moogle的,右邊是Chocobo的,注意到,Chocobo的下拉選單是在兩個按鈕之上哦,往下看之前,可以先想想,這樣的介面是如何排出來的!

接下來我們就先針對 Moogle 的介面做說明,我們今天是從元件庫裡拉出一個spinner的元件到畫面中,取代昨天輸入框的這個介面元素

這個元素我們將之命名為"spn_signal",那要如何給值呢,請再往下看嘍~
切換到 MoogleActivity.java 的程式視窗,我們先定義一個全域的字串陣列變數

private String[] mSingals = new String[] {
    "壹", "貳", "參", "肆", "伍", "陸", "柒", "捌", "玖", "拾"
};

接著有個關鍵,要定義一個ArrayAdapter的物件

//設定下拉選單(Spinner)物件,mSpnSignal是已經定義好的全域變數
mSpnSignal = (Spinner)findViewById(R.id.spn_signal);
ArrayAdapter<String> adapterSignal = new ArrayAdapter<String>(
    this, //Context
    android.R.layout.simple_spinner_item, //選單格式
    mSingals	//選單內容
);
//選單外觀
adapterSignal.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//將adapter放入spinner物件中
mSpnSignal.setAdapter(adapterSignal);

這樣做完後,執行後就能看到上面左邊的畫面了,再來要定義「傳送」巴特(button)的動作:

mBtnSend.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        //取得 EditText 的內容
        mMessage = mEdtMessage.getText().toString();
        //準備切換的意圖
        Intent intent = new Intent(v.getContext(), ChocoboActivity.class);
        //準備切換時要傳遞的包裹
        Bundle bundle = new Bundle();
        //在包裹內放入一個key為signal_string的選單選擇文字
        bundle.putString("signal_string", mSpnSignal.getSelectedItem().toString());
        //在包裹內放入一個key為signal_id的選單選擇值
        bundle.putInt("signal_id", mSpnSignal.getSelectedItemPosition());
        bundle.putString("message", mMessage);
        intent.putExtras(bundle);
        //切換
        startActivity(intent);
    }
});

這邊有兩段指令

//這個是取出被選擇項的內容,也就是定義的文字,因此,要記得將之"轉成字串(toString())
mSpnSignal.getSelectedItem().toString()
//此指令在取得被選項的"位置",也就是選項中的第幾個,起始從"0"開始
mSpnSignal.getSelectedItemPosition()

完成了 Moogle 的設定後,再來看到 Chocobo 嘍~
有思考過,上面說明的那個介紹是如何"佈置"出來的嗎開心
其實概念很簡單,最上層就是一個縱向的LinearLayout再包進「Spinner以及橫向的LinearLayout」

Chocobo的 Spinner 我們就命名為"spn_chocobo_signal"吧,接下來直接看到"ChocoboActivity.java"這邊要做什麼動作,首先是取出包裹裡的東西:

//從包裹取出傳來的內容
Bundle bundle = this.getIntent().getExtras();
//要注意,這裡得跟傳來的包裹"標籤"名稱一樣哦!
mSignalString = bundle.getString("signal_string");
mSignalId = bundle.getInt("signal_id");
mMessage = bundle.getString("message");

再來針對 Chocobo 的下拉選單設定,一定要給予一個"內容相同"之字串陣列的全域變數

private String[] mSingals = new String[] {
    "壹", "貳", "參", "肆", "伍", "陸", "柒", "捌", "玖", "拾"
};

然後,是spinner與adapter的定義

Spinner spnChocobo = (Spinner)findViewById(R.id.spn_chocobo_signal);
ArrayAdapter<String> adapterSignal = new ArrayAdapter<String>(
    this, 
    android.R.layout.simple_spinner_item, 
    mSingals
);
adapterSignal.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spnChocobo.setAdapter(adapterSignal);
spnChocobo.setSelection(mSignalId);

有發現內容都跟上面一樣嗎,在下絕對不會承認是自己想偷懶汗
其實是還多了最後一行

//設定選單到"第mSignalId項"
spnChocobo.setSelection(mSignalId);

如此,就把我們今天需要做出來的部份弄得差不多嘍,若您是直接延用昨天的範例,原則上是八九不離十了,若您是新增專案的話,建議您再自行依昨日的範例補上其餘的部份哦!

接下來,同場加映:
到目前為止,我們的程式碼都加是寫在onCreate()裡面,雖然沒有什麼不對,但感覺就是亂!
所以我們來稍微"重構(refactor)一下,我們將定義物件的那幾行程式(如下)反白選擇起來,

//下拉選單
mSpnSignal = (Spinner)findViewById(R.id.spn_signal);
//輸入框
mEdtMessage = (EditText)findViewById(R.id.edt_message);
//按鈕
mBtnSend = (Button)findViewById(R.id.btn_send);

然後在其上點滑鼠右鍵,選到"Refactor"可以延伸出一個子分頁出來

選擇"Extract Method..."會跳出下面這個視窗

由上而下看到:
**Method name:**函式的名稱
**Access modifier:**開放類型
**preview:**預覽

確定之後,原本的程式區塊就會被移到該函式裡,變成下面這樣的函式呈現

private void setView() {
    //下拉選單
    mSpnSignal = (Spinner)findViewById(R.id.spn_signal);
    //輸入框
    mEdtMessage = (EditText)findViewById(R.id.edt_message);
    //按鈕
    mBtnSend = (Button)findViewById(R.id.btn_send);
}

再來將剩下的定義動作的部份如法泡製,取名為"setAction"即可,也許有人會問,這樣做有什麼好處,我們程式都寫在onCreate()裡的能動、又不會出問題,何必這麼麻煩!
說明前,我們先來看到,這時候的onCreate()長什麼樣子:

//設定下拉選單(Spinner)物件,mSpnSignal是已經定義好的全域變數
mSpnSignal = (Spinner)findViewById(R.id.spn_signal);
ArrayAdapter<String> adapterSignal = new ArrayAdapter<String>(
    this, //Context
    android.R.layout.simple_spinner_item, //選單格式
    mSingals	//選單內容
);
//選單外觀
adapterSignal.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//將adapter放入spinner物件中
mSpnSignal.setAdapter(adapterSignal);

0

有留意到嗎,主要的程式區塊變得很"乾淨",同時,我們可以一眼就看出,我們依序做了什麼事,要改動某處,也只要到該函式裡修改即可。再來,就是該函式的可被"重複使用性"就大幅地提升了!

這樣可以理解嗎^_^
程式碼請自行從 Mosil's GitHub下載哦

《飛(?)"鳥"傳書 Day 14 - Android - 語言


上一篇
Day 12 - Android - 飛(?)"鳥"傳書
下一篇
Day 14 - Android - 語言
系列文
Android 學習手札30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
海綿寶寶
iT邦大神 1 級 ‧ 2012-10-07 17:05:57

不是我愛嫌
這個 emulator 做出來的畫面
實在很難看
打嗑睡

實機上應該漂亮多了吧
忙


我要留言

立即登入留言