哈~~囉~~
今天要來講講關於下拉式選單(清單)(spinner)
對我而言這是個在實戰中蠻常用的元件
而且每次遇到的狀況又特別雞歪_(:3」∠)_
之前找關於這方面的資料時,頭真的很痛
因為當時第一次使用這個元件、找資料時
找到的資料都是固定內容的選單...連官網也不例外(´・_・`)
附上官網連結,去參考一下就知道啦
這裏->https://developer.android.com/guide/topics/ui/controls/spinner
但當時還是蔡逼八時的專案又是要求選單內容要隨著內容改變,最好要能擴充的
有鑒於中文資料偏少,故寫下一篇文章作紀錄
那本篇文章中,將會示範官網的這種固定式的做法以及以ArrayList做出可變動的選單兩種
以及也會示範動態變更選單內容的做法~(・ωー)~☆
那就上功能吧!
以及Github
https://github.com/thumbb13555/SpinnerExample
1.拉介面
上圖示範中我放兩個spinner,上方的是完全仿照官網的做法處理
下方的是使用ArrayList完成動態陣列,而下方兩個按鈕分別可以針對此陣列(選單內容)做增減
拉介面並不是什麼很困難的事...所以我直接放吧(`・ω・´)+
這時候可以執行一下,看看介面的程式碼有沒有錯哦(•ө•)♡
2.加入array.xml的陣列資料
前面也說了,這篇文章中將會示範兩種設置Spinner的作法
那首先從官網示範的來吧~
簡單說明一下,官網的作法是
1.在資源檔中建立一個放陣列的資源
2.呼叫陣列適配器(ArrayAdapter)
3.將資料以資源檔的形式放入ArrayAdapter內
那我們就按照官網的作法來一次吧~
2-1載入介面資源檔
首先在資源檔資料夾
路徑: res/values/之下建立一個新的資源檔,我取名叫array.xml
新增方法:
在values資料夾上點右鍵->New->Values Resourece File即可
接著把資料放進去~點開這個檔案然後把以下內容放入o(メ・・)=日☆
就完成設置囉(・ω・)b
3.設置第一個spinner(綁定資源檔陣列)
把焦點切到MainActivity.java這邊
要設置一個Spinner的具體作法如下
1.連結介面實體
2.宣吿ArrayAdapter
3.將資源檔(陣列)嵌入ArrayAdapter
4.用Spinner的setAdapter方法載入ArrayAdapter內
了解後實際來操作吧
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner1 = findViewById(R.id.spinnerEX1);
Spinner spinner2 = findViewById(R.id.spinnerEX2);
Button btAdd = findViewById(R.id.buttonADD);
Button btRemove = findViewById(R.id.buttonRemove);
ArrayAdapter adapter1 = ArrayAdapter.createFromResource(this
,R.array.planets_array,android.R.layout.simple_dropdown_item_1line);
spinner1.setAdapter(adapter1);
}
}
ArrayAdapter.createFromResoure中,要丟給它的基本上就是
1.context(上下文)
2.資源檔陣列
3.下拉介面樣式(一般使用android提供的單行下拉就可以囉)
Okay,做到這邊可以先執行看看,陣列應該會成功載入到Spinner囉
4.設置第二個spinner(動態陣列&點擊事件)
4-1 陣列載入至Spinner
接著要設置第二個spinner-以ArrayList完成的陣列
基本上邏輯也是一樣,但是ArrayAdapter有稍微改了一點點
我直接Po並標明重點吧
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner1 = findViewById(R.id.spinnerEX1);
Spinner spinner2 = findViewById(R.id.spinnerEX2);
Button btAdd = findViewById(R.id.buttonADD);
Button btRemove = findViewById(R.id.buttonRemove);
ArrayAdapter adapter1 = ArrayAdapter.createFromResource(this
,R.array.planets_array,android.R.layout.simple_dropdown_item_1line);
spinner1.setAdapter(adapter1);
ArrayList arrayList = new ArrayList<Integer>();
for (int i = 0;i<5;i++){
arrayList.add(i);
}//製作陣列
ArrayAdapter adapter2 = new ArrayAdapter(this
,android.R.layout.simple_dropdown_item_1line,arrayList);
spinner2.setAdapter(adapter2);
}
}
可以看到兩者之間有點差異性
ArrayAdapter.createFromResoure需要載入
1.context(上下文)
2.資源檔陣列
3.下拉介面樣式
而 new ArrayAdapter則是載入
1.context(上下文)
2.下拉介面樣式
3.要呈現的陣列(僅可ArrayList)
然後做到這邊可以再執行一次,看看效果如何(・∀・)
4-2 加入點擊事件
Spinner的點擊事件,是使用setOnItemSelectedListener並配合AdapterView.OnItemSelectedListener完成
一樣直接上程式
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner1 = findViewById(R.id.spinnerEX1);
Spinner spinner2 = findViewById(R.id.spinnerEX2);
Button btAdd = findViewById(R.id.buttonADD);
Button btRemove = findViewById(R.id.buttonRemove);
ArrayAdapter adapter1 = ArrayAdapter.createFromResource(this
,R.array.planets_array,android.R.layout.simple_dropdown_item_1line);
spinner1.setAdapter(adapter1);
ArrayList arrayList = new ArrayList<Integer>();
for (int i = 0;i<5;i++){
arrayList.add(i);
}//製作陣列
ArrayAdapter adapter2 = new ArrayAdapter(this
,android.R.layout.simple_dropdown_item_1line,arrayList);
spinner2.setAdapter(adapter2);
spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(view.getContext(),parent.getSelectedItem().toString()/*這行可直接取得選中內容*/,Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
}
}
4-3 修正spinner的自動預設事件
寫到這邊,建議讀者再Run一次程式,基本上大體上是沒有問題的
但是如果仔細看會發現...為何每次一重新執行,Toast就會直接彈出了呢?
原因是出在於,setOnItemSelectedListener本身在開啟時,會直接先把第一個選項載入
這時候如果你的選項一有連帶動作,恐怕就會誤觸發,造成一些問題(´・_・`)
因此我這樣做
public class MainActivity extends AppCompatActivity {
Boolean firstTime = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner1 = findViewById(R.id.spinnerEX1);
Spinner spinner2 = findViewById(R.id.spinnerEX2);
Button btAdd = findViewById(R.id.buttonADD);
Button btRemove = findViewById(R.id.buttonRemove);
ArrayAdapter adapter1 = ArrayAdapter.createFromResource(this
,R.array.planets_array,android.R.layout.simple_dropdown_item_1line);
spinner1.setAdapter(adapter1);
ArrayList arrayList = new ArrayList<Integer>();
for (int i = 0;i<5;i++){
arrayList.add(i);
}//製作陣列
ArrayAdapter adapter2 = new ArrayAdapter(this
,android.R.layout.simple_dropdown_item_1line,arrayList);
spinner2.setAdapter(adapter2);
spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (firstTime){firstTime = false;}
else{
Toast.makeText(view.getContext(),parent.getSelectedItem().toString(),Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
}
}
就能防止誤動作囉~(看不懂我在幹嘛的...小力去撞豆腐)
5.加入按鈕使選項內容能自由刪減
關於spinner內容動態刪減的這個問題,我曾經花了一點時間去方法
後來我發現...
只要修改上面被適配器(ArrayAdapter)所綁定的陣列就可以了
什麼notifyChange啊什麼的...完全無需處理
直接Po...
public class MainActivity extends AppCompatActivity {
Boolean firstTime = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner1 = findViewById(R.id.spinnerEX1);
Spinner spinner2 = findViewById(R.id.spinnerEX2);
Button btAdd = findViewById(R.id.buttonADD);
Button btRemove = findViewById(R.id.buttonRemove);
ArrayAdapter adapter1 = ArrayAdapter.createFromResource(this
,R.array.planets_array,android.R.layout.simple_dropdown_item_1line);
spinner1.setAdapter(adapter1);
ArrayList arrayList = new ArrayList<Integer>();
for (int i = 0;i<5;i++){
arrayList.add(i);
}//製作陣列
ArrayAdapter adapter2 = new ArrayAdapter(this
,android.R.layout.simple_dropdown_item_1line,arrayList);
spinner2.setAdapter(adapter2);
spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (firstTime){firstTime = false;}
else{
Toast.makeText(view.getContext(),parent.getSelectedItem().toString(),Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
btAdd.setOnClickListener((v)->{
arrayList.add(arrayList.size());
});
btRemove.setOnClickListener((v -> {
if (arrayList.size()!=0){
arrayList.remove(arrayList.size()-1);
}
}));
}
}
結語
前文也有說...spinner我也算是搞了一小段時間
有時候越簡單的元件喔,因為常見,所以來自客戶或老闆他們的想像力就多
我這個還沒有把樣式包上去....不然一般而言Spinner都會放個樣式吧~
然後動態更新Spinner內容也是找了好多文章才發現根本就是自己把他想像得太難了
畢竟大家都會覺得...應該就跟RecyclerView的notifyDataSetChanged()一樣吧..的想法
哎,也算是繞了一大圈啦XD
另外,最近我偶爾會收到來自讀者的反饋,有些人也會寄Mail問我問題
我這裡強調
我非常歡迎這種行為
沒看清楚嗎?
我非常歡迎這種行為
我非常歡迎這種行為
我非常歡迎這種行為(・ωー)~☆
而且我發現寄mail來問的比較多XD 大家都很低調
感謝大家的鼓勵,我會再努力發各種Android的大小事的
希望大家都可以在我這憋學到一點東西
那文章到此,感謝各位~
留言列表