iT邦幫忙

DAY 25
2

Android 學習手札系列 第 25

Day 25 - Android - 簡介與列表

Day 21 - Android - 化身該篇裡面介紹到一個列表時常用的元件-ListView,當天只有帶到預設所提供的最簡意樣式,今天要將之延伸下去。

另外,昨天最後的一段有想到如何實作了嗎,程式碼可以前往 Mosil's GitHub 去下載嘍
Day 21 - Android - 化身中,針對每位角色只有名字的列表,好像沒有什麼感覺,而且稍嫌簡略了些~所以今天我們將再利用另外一個預設的樣式。依序前例,就直接再延用昨天的程式繼續下去嘍~

請先到strings.xml裡面增加一段字串內容

<string-array name="creation">
    <item>Final Fantasy VII</item>
    <item>Final Fantasy VI</item>
    <item>Final Fantasy V</item>
</string-array>

這個字串列表的資料是三個角色出現的作品,請注意需要跟原本的字串數量是一樣的,還有其順位的狀況哦!
再來,我們今天要用到的預設樣式名稱為:simple_list_item_2。這個樣式的長相如下

就是一上一下的文字,我們就直接用來呈現名字(上)以及出現作品(下),我們先在 Moogle3Activity.java 的 onCreate() 區段之上,宣告兩個全域的字串常數,用途請往下看:

private final String NAME = "name";
private final String CREATION = "creation";

先來看到這段

因為這次可以使用的元素變多了,所以這次要改用SimpleAdapter來取代原本的ArrayAdapter<String>,而透過上圖我們也看到,需要傳遞的參數也不一樣了,我們就一項一項的來介紹跟增加!
第一個參數:context,就是把現在的這個context-this給放進去。
第二個參數:data,要呈現的資料。而這邊列表中的每個內容裡都需要用到兩個字串元素,而這邊的data自然就不會是"只有"兩個字串,而是兩個等量的字串陣列,先來看到這邊的宣告

/* 先接出兩個來自 strings.xml 裡的字串陣列 */
String[] names = getResources().getStringArray(R.array.leader);
String[] creation = getResources().getStringArray(R.array.creation);
//宣告一個ArrayList來存放這兩個陣列
ArrayList<HashMap<String, String>> leaders = new ArrayList<HashMap<String, String>>();

再回頭看一次上圖,這個參數的格式是一個具key以及value格式的陣列,所以我們用ArrayList<HashMap<String, String>>()來做為這次的類型,接下來就是將兩個陣列放進去

for(int i = 0; i < names.length; i++){
    HashMap<String, String> leader = new HashMap<String, String>();
    leader.put(NAME, names[i]);
    leader.put(CREATION, creation[i]);
    leaders.add(leader);
}

承如上面所說,這兩個字串必要是"等量"這段程式才不會發生問題!

第三個參數:from指的就是從data裡面的哪個key取值,所以這裡放得是我們兩個"key"的字串陣列:

new String[]{NAME, CREATION}

第四個參數:to放到哪兩個介面元素裡,

new int[]{android.R.id.text1, android.R.id.text2}

下面是這段的完整片段

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_moogle3);
    /* 先接出兩個來自 strings.xml 裡的字串陣列 */
    String[] names = getResources().getStringArray(R.array.leader);
    String[] creation = getResources().getStringArray(R.array.creation);
    //宣告一個ArrayList來存放這兩個陣列
    ArrayList<HashMap<String, String>> leaders = new ArrayList<HashMap<String,String>>(); 
    
    for(int i = 0; i < names.length; i++){
        HashMap<String, String> leader = new HashMap<String, String>();
        leader.put(NAME, names[i]);
        leader.put(CREATION, creation[i]);
        leaders.add(leader);
    }
    setListAdapter(
        new SimpleAdapter(
                this, 
                leaders,
                android.R.layout.simple_list_item_2,
                new String[]{NAME, CREATION}, 
                new int[]{android.R.id.text1, android.R.id.text2}));
    
    mBtnBack = (Button)findViewById(R.id.btn_moogle3_back);
    mBtnBack.setOnClickListener(btnClick);
}

如此一來,就完成今天的部份嘍!
而這個介面的長相,當然不只是這樣,請看到下圖

這邊能看到預設的樣式就有這麼多種,而這邊在下當然是…不會全部將之介紹完畢XD
不過,明天將帶著大家如何"自定"屬於自己的介面。

========================================================
再來,回頭帶各位來看看昨天的程式部份,原本在Day 17 - Android - 無中生有的 Moogle2 裡,在其 setView() 中產生 checkbox 時,就是很單純的用迴圈跑過他,沒有考慮到我們要再將之提取出來使用的狀況,所以我們要先定義一個全域的checkbox陣列,並在迴圈裡將之放入

...
private ArrayList<CheckBox> mChkBoxs;
...

public void onCreate(Bundle savedInstanceState) {
...
    //在這裡給予初值
    ArrayList<Integer> number = new ArrayList<Integer>();
...
}

private void setView(){
    try{
        ...
        for(int i=0; i<=mMoogles.length; i++){
            CheckBox chkMoogle = new CheckBox(this);
            chkMoogle.setId(i);
            chkMoogle.setText(mMoogles[i]);
            chkMoogle.setOnCheckedChangeListener(chkMoogles);
            mLlMoogles.addView(chkMoogle);
	    //多了這一行,將新增的chkbox給放到陣列中
            mChkBoxs.add(chkMoogle);
        }
    ...

到這邊算是完成我們的介面佈置了,再來是隨機邏輯的部份

ArrayList<Integer> number = new ArrayList<Integer>(); 
for(int i = 0; i <= bundle.getInt("signal_id"); i++){
    int no = 0;
    do{
        no = (int) (Math.random() * mMoogles.length);        		
    } while(number.contains(no));
    number.add(no);
    mChkBoxs.get(no).setChecked(true);
}

在下的做法,是利用一個數值陣列記下亂數產出的數值,目前在於不重覆
然後用迴圈來亂數產出我們從 Chocobo 傳來的數量後,除了將不重覆者放入數值陣列中外,最重要的就是讓該 Checkbox 被勾選起來,而各位也能夠透過上面的程式碼看到,我們從第n個checkbox陣列中取出來設定(setChecked)勾選。而做到這邊就能看到被隨機勾選起來的成果了。
而在下這個做法只是其中一種,若是各位有不同的做法或是想法歡迎提出哦^_^
不過,別忘了,最後還有一個我們昨天提到的重點,我們要將資料傳回去,這段程式被寫在btnBackClick這個偵聽函式裡,

Intent intent = new Intent();
String message = "";
for(int i = 0; i < mChkBoxs.size(); i++){
    if(mChkBoxs.get(i).isChecked()){
        if(message.equals("")){
            message = "選擇了: " + mChkBoxs.get(i).getText().toString();
        } else {
            message += ", " + mChkBoxs.get(i).getText().toString();
        }
    }
}
intent.putExtra("message", message);
setResult(Number.MOOGLE2, intent);

其實就是整個迴圈跑過所有的checkbox,來找出有被勾選的項次,然後兜好成 message 字串。
最後就是回到 Chocobo 的 onActivityResult() 區段來做我們的呈現動作即可。

private final String NAME = "name";
private final String CREATION = "creation";

0

今天再這樣複習一次,不知道各位對 startActivityForResult 的機制是否更有印象了呢?

Day 24 - Android - 溝通《 》Day 26 - Android - 第二個世界元素


上一篇
Day 24 - Android - 溝通
下一篇
Day 26 - Android - 第二個世界元素
系列文
Android 學習手札30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
mosil
iT邦新手 4 級 ‧ 2012-10-19 23:42:33

怪~疑惑
最後一段的程式明明不是這樣貼的樣,修改了幾次還是長那樣暈
這邊再貼一次試試看好了

&lt;pre class="c" name="code">
@Override
protected void onActivityResult(
        int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //從回傳碼來決定要對誰做動作
    switch(resultCode){
        case Number.MOOGLE2:
            Toast.makeText(this
                    , data.getStringExtra("message")
                    , Toast.LENGTH_LONG).show();
            break;
    }
}
mosil iT邦新手 4 級 ‧ 2012-10-19 23:44:23 檢舉

看來在這裡是正常的,不知道發生什麼事了失神

我要留言

立即登入留言