2012-07-16

Android下拉選單(spinner)應用(三) - 連動式下拉選單

因為有人問我怎麼做連動式下拉選單

所以就再寫這篇文章說明怎麼做連動式下拉選單好了

連動式下拉選單也是蠻常用的一個功能,比如縣市選擇....等

下面就貼上程式碼直接實作:

main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFFFFF"
    >
    <Spinner android:id="@+id/type" 
        android:layout_width="fill_parent" 
          android:layout_height="45dp"
          android:layout_marginLeft="75dp"
          android:layout_marginRight="20dp"
        android:layout_marginTop="7dp" 
         android:drawSelectorOnTop="true"
         android:layout_alignParentRight="true" 
    />
       <Spinner android:id="@+id/type2" 
        android:layout_width="fill_parent" 
          android:layout_height="45dp"
          android:layout_marginLeft="75dp"
          android:layout_marginRight="20dp"
          android:layout_marginTop="3dp" 
         android:drawSelectorOnTop="true"
         android:layout_alignParentRight="true" 
         android:layout_below="@id/type" 
         />
      
</RelativeLayout>



DoubleSpinnerActivity
package jim.demo.DoubleSpinner;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

public class DoubleSpinnerActivity extends Activity {
    
  private String[] type = new String[] {"茶類", "果汁類"};
  private String[] tea = new String[]{"紅茶","綠茶","烏龍綠","青茶"};
  private String[][] type2 = new String[][]{{"紅茶","綠茶","烏龍綠","青茶"},{"柳丁汁","西瓜汁","烏梅汁"}};
  private Spinner sp;//第一個下拉選單
  private Spinner sp2;//第二個下拉選單
  private Context context;

     ArrayAdapter<String> adapter ;

     ArrayAdapter<String> adapter2; 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        context = this;
        
        //程式剛啟始時載入第一個下拉選單
        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, type); 
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
        sp = (Spinner) findViewById(R.id.type); 
        sp.setAdapter(adapter);
        sp.setOnItemSelectedListener(selectListener);
        
        //因為下拉選單第一個為茶類,所以先載入茶類群組進第二個下拉選單
        adapter2 = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, tea); 
        adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
        sp2 = (Spinner) findViewById(R.id.type2);
        sp2.setAdapter(adapter2);
    }
    
    //第一個下拉類別的監看式
    private OnItemSelectedListener selectListener = new OnItemSelectedListener(){
        public void onItemSelected(AdapterView<?> parent, View v, int position,long id){
         //讀取第一個下拉選單是選擇第幾個
            int pos = sp.getSelectedItemPosition();
            //重新產生新的Adapter,用的是二維陣列type2[pos]
            adapter2 = new ArrayAdapter<String>(context,android.R.layout.simple_spinner_item, type2[pos]);
            //載入第二個下拉選單Spinner
            sp2.setAdapter(adapter2);
        }
      
        public void onNothingSelected(AdapterView<?> arg0){

        }

    };
}

執行後畫面
起啟畫面

選擇第一個下拉選單

選擇第一個下拉選單後,連動第二個下拉選單

 第二個下拉選單出現不同之內容

說明:
            1.我們在main.xml中拉進二個Spinner做連動式下拉選單

            2.定義三個私有陣列type、 tea、type2

            3.sp第一個下拉選單、sp2第二個下拉選單

            4.adapter第一個下拉選單的資料橋接器、adapter2第二個下拉選單的資料橋接器 

            5.在還沒連動之前(程式起啟)必須為下拉選單給值,所以把type給sp、tea給sp2
               也可以直接用type2[0]就好(程式是死的,人是活的)

            6.選擇第一個下拉選單就會去觸發OnItemSelectedListener重新給sp2資料

後記:
            Spinner下拉選單不過就幾個重點要把握而已

            Spinner本體、Adapter資料橋接器、OnItemSelectedListener動作監看式這三個

            而Spinner時常會使用到Array陣列,所以陣列也需要多了解,就為您介紹到這,謝謝。

27 則留言:

  1. 真是非常感謝您的這篇文章
    幫助我很多
    但我想請教你一下
    我目前所做的app正好是類似縣市選擇那種
    而我有3個spinner
    現在卡在
    不知如何寫"第二個下拉類別的監看式"
    就是要讀取第二個下拉選單是選擇第幾個
    這邊不知該如何寫
    請幫我解答
    謝謝

    回覆刪除
  2. private String[] tea = new String[]{"紅茶","綠茶","烏龍綠","青茶"};

    private String[][] type2 = new String[][]{{"紅茶","綠茶","烏龍綠","青茶"},{"柳丁汁","西瓜汁","烏梅汁"}};


    第2個下拉是選單,內容要連前一個的項目都打出來嗎???我要做好幾類的,東西共60幾個,都得打出來嗎???

    回覆刪除
  3. 我的類別就又5至6個了,各個類別都有10幾樣,我怎麼試都改不成功,請問大概怎麼改??

    由其實這邊
    int pos = sp.getSelectedItemPosition();

    adapter2 = new ArrayAdapter(context,android.R.layout.simple_spinner_item, type2[pos]);

    sp2.setAdapter(adapter2);
    }

    回覆刪除
    回覆
    1. 你要改的是陣列吧

      把一維陣列改成你的5~6個

      二維陣列戶成你那各類別中的10幾樣

      先了解程式在寫什麼,再變化為自己需要的

      光改程式是學不到東西的,共勉之~~

      刪除
  4. 請問一下
    我是想作三個關聯式下拉選單
    我遇到一些問題
    請先看我部分的程式碼

    private String[] type = new String[] {"茶類","果汁類"};
    private String[][] type2 = new String[][]{{"紅茶","綠茶","烏龍茶",},{"柳丁汁","西瓜汁","葡萄汁"}};
    private String[][] type3 = new String[][]{{"紅茶好喝"},{"綠茶不錯"},{"烏龍茶還好"},{"柳丁汁好棒"},{"西瓜汁還可以"},{葡萄汁讚}};


    //讀取第二個下拉選單是選擇第幾個
    int pos2 = sp2.getSelectedItemPosition();

    //重新產生新的Adapter,用的是二維陣列type3[pos2]

    adapter3 = new ArrayAdapter (context,android.R.layout.simple_spinner_item, type3[pos2]);

    //載入第三個下拉選單Spinner
    sp3.setAdapter(adapter3);

    三個關聯下拉式選單
    如果是選擇 茶類>紅茶>紅茶好喝 or 茶類>綠茶>綠茶不錯
    這些都不會有問題
    問題在於
    我選擇 果汁類>柳丁汁>紅茶好喝 果汁類>西瓜汁>綠茶不錯

    第三個下拉式選單好像也必須要跟第一個下拉選單有關聯這邊要怎弄?


    回覆刪除
  5. 可以稍微示範一、二維都是很多樣種的嗎???

    回覆刪除
    回覆
    1. 不好意思!不是很清楚您的問題

      可能要麻煩您說清楚一點,謝謝。

      刪除
  6. 作者已經移除這則留言。

    回覆刪除
  7. 請問第一個下拉選單的樣式要怎麼跟第二個相同...我一直找不到原因!!

    回覆刪除
    回覆
    1. 第一個下拉是類別、第二個下拉是細項
      應該是第二個下拉要跟著第一個
      所以我不是很清楚你說的第一個下拉樣式要跟第二個相同?
      可以再清楚說明你的問題點嗎?我好幫你解惑。

      刪除
    2. 不好意思 我說的樣式是指~就是第一個下拉選單下拉時選項旁邊會有一個綠色點,但是第二個下拉選單的樣式卻不是有綠色點的樣式@@

      要怎麼統一兩種下拉選單的樣式@@

      刪除
    3. adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
      這個指的是下拉選單的樣式,第二個下拉會出現沒有樣式是因為我程式中
      在第一個下拉類別的監看式中重新產生新的Adapter後沒有加入樣式
      所以只要在重新產生新的Adapter後面加入上面這個樣式就可以了。

      刪除
    4. OKOK 了解了~~謝謝您阿

      刪除
  8. 假如我下面再加一個Textview來顯示,我選到的第二個下拉式的內容

    我加的內容該怎打?? (Textview已命名為tt)

    謝謝

    回覆刪除
    回覆
    1. 和第一個下拉監看式一樣
      在第二個下拉監看式中加入
      //讀取第二個下拉選單是選擇第幾個
      int pos2 = sp2.getSelectedItemPosition();
      tt.setText(sp2.getItem(pos2));

      刪除
    2. 所以還要在加個第二個下拉監看式??

      刪除
  9. 有辦法讓下拉式選單跟資料庫做聯結麻

    回覆刪除
  10. 不用在res這個資料夾里設文字檔嗎

    回覆刪除
    回覆
    1. 你好:

      不是很懂你的意思,res內本來就有文字檔,你設文字檔的用意是什麼?

      刪除
  11. 定義三個私有陣列type、 tea、type2??
    這是要設在res嗎

    回覆刪除
    回覆
    1. 你好:

      我猜想你應該是相知道怎麼把陣列設在res的values內吧

      其實兩種方式都是可行的,要看你想怎麼用

      存在res的values方式:

      在values內開一個XML檔res/values/arrays.xml

      裡面放:
      <resources>
      <string-array name="select_dialog_items">
      <item>Start</item>
      <item>Stop</item>
      <item>Delete</item>
      </string-array>
      </resources>

      Java內引用:
      String[] data = this.getResources().getStringArray(R.array.select_dialog_items);

      其實還是一樣的,我用的方式只是比較直接而已,直接寫在Java檔內,看你想怎麼用都可以

      PS:程式是死的,人是活的,方法不會只有一種,要看你想怎麼用。

      刪除
  12. 請問大大為什麼我的背景不能像你一樣都暗掉呢?????
    就是在點選任一個選單後 , 只有選單是亮的,背景是暗的這樣... ??

    回覆刪除
    回覆
    1. 而且也沒有像版主一樣.... 有那種圈圈加一個的點的樣子除非是這樣打
      -> adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
      怎麼會這樣 , 是版本的問題嗎?

      刪除
  13. 你好 請問一下 如果想要點選後 跳去另一個Activity 有辦法嗎? 謝謝

    回覆刪除
  14. 如果想將所選得內容,透過"按鈕"傳送到資料庫裡該怎麼做呢?

    回覆刪除
  15. 請問一下如果後面果汁要加上價格加總呢?

    回覆刪除

您的寶貴建議是我前進的動力!