各位好~~ヾ(^∇^)
今天的主題是單選按鈕(Radio Button)的使用
在Android 設計中,不知道您是否遇過需要單訓的情形呢?
而如果這時你去搜尋Radio Button關鍵字的話
你應該會搜出很多教學。
但是!!(/・0・)
通常這些教學多數都是固定量的Radio Button
也就是使用xml介面寫好需要量的Radio Button,在去做控制。
不過~~在實際專案中大多數的需求其實都是要會變動的,反而要求不變動的應該算少...
也因如此才寫了這篇筆記_(:3」∠)_
在開始之前,以下是幾個建議的搜尋關鍵字,方便在搜尋的時候可以搜出自己想要的東西
dynamic radio button
自動生成Radio button
等以上兩個關鍵字,兩方配合一下就可以搜出"如何自動調整Radio Button的數量"要求囉!
(不過這篇主題就是要寫這個...)
另外,因為本次需要用到AlertDialog的相關技術
故,如果對於呼叫AlertDialog忘記的朋友
可以參考這篇 ->http://thumbb13555.pixnet.net/blog/post/310777160
另外,不想浪費時間的朋友,請直接拉到文章最後,有提供複製貼上就可以使用的Code (・ω・)b
OK,那就上範例
主畫面顯示範例
AlertDialog內顯示範例
奉上Github
https://github.com/thumbb13555/DynamicRaidoButtonExample
開始!
0.功能描述
- 在主畫面中按下按鈕後即顯示與轉輪號碼相等之RadioButton數量
- 按下右邊按鈕後即以AlertDialog顯示與轉輪號碼相等之RadioButton數量
- 主畫面中的RadioButton點選後顯示該RadioButton所對應之編號與標籤內容
- AlertDialog內點選完RadioButton後,點選OK即顯示該RadioButton所對應之編號與標籤內容
1.新增介面
這次要實作兩個介面,一個是主畫面;另一個是Dialog用的畫面
於是我的layout檔案中有兩個,兩個都要記得複製喔~
然後奉上兩個介面連結
activity_main.xml
choose_dialog.xml
1.自動增減RadioButton的核心代碼介紹
核心代碼:
/*取得標籤*/
int rgAmount = numberPicker.getValue();//根據轉輪決定要有幾個標籤
ArrayList<String> rgLabel = new ArrayList<>();
for (int i = 0; i < rgAmount; i++) {
rgLabel.add("第" + (i + 1) + "項目");
}
/*===================在此已完成標籤數量===================*/
/*根據標籤數量設置幾個RadioButton*/
LinearLayout layoutMain = findViewById(R.id.linearLayout_Main);//連結介面
RadioGroup radioGroup = new RadioGroup(this);//新增RadioButton方法
radioGroup.setOrientation(RadioGroup.VERTICAL);
layoutMain.removeAllViewsInLayout();//清除原介面中的物件
RadioGroup.LayoutParams rlTable;//設置界面
for (int i = 0; i < rgLabel.size(); i++) {//以標籤數量決定新增幾個RadioButton
RadioButton radioButton = new RadioButton(this);
radioButton.setText(rgLabel.get(i));//設置每個RadioButton內的標籤名稱
rlTable = new RadioGroup.LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT
, RadioGroup.LayoutParams.MATCH_PARENT);
radioGroup.addView(radioButton, rlTable);//將創好的物件加入
}
layoutMain.addView(radioGroup);//將物件加入layout內
整體就如以上示範,只要複製就可以完成今天的基本需求
其整個邏輯重點就是在於"先把RadioButton創建好,然後再把RadioButton丟入RadioGroup內;最後再把RadioGroup丟入指定的Layout內"
這樣的一個過程
至於RadioGroup與RadioButton之間的關係
可以理解為RadioGroup是一個盤子
RadioButton是盤子裡的豆子
然後layout是一張桌子
一個桌子有很多盤子,每個盤子自成一區去控制他們
...我知道比喻很爛,不過大概是這樣...(´д`)
看過了核心代碼後,接下來就是加入周邊的程式了
2.置入功能
看過了核心代碼後,接下來就是要連結周邊元件
首先是onCreate內的框架設置
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btDisplay = findViewById(R.id.button_display);
Button btDialog = findViewById(R.id.button_showDialog);
NumberPicker numberPicker = findViewById(R.id.numberPicker);
numberPicker.setMaxValue(5);
numberPicker.setMinValue(1);
btDisplay.setOnClickListener((v) -> {
//點擊左側按鈕後的行為
});
btDialog.setOnClickListener(v -> {
//點擊右側按鈕後的行為
});
}
}
首先先寫一個副程式叫做setRadioAction,並將numbePicker元件傳入
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btDisplay = findViewById(R.id.button_display);
Button btDialog = findViewById(R.id.button_showDialog);
NumberPicker numberPicker = findViewById(R.id.numberPicker);
numberPicker.setMaxValue(5);
numberPicker.setMinValue(1);
btDisplay.setOnClickListener((v) -> {
setRadioAction(numberPicker);
});
btDialog.setOnClickListener(v -> {
});
}
/**
* 設置主畫面上的RadioButton
*/
private void setRadioAction(NumberPicker numberPicker) {
}
}
接著焦點放在這個副程式內,首先我們要先來生成radioButton附帶的標籤
於是程式長這樣
/**
* 設置主畫面上的RadioButton
*/
private void setRadioAction(NumberPicker numberPicker) {
/*取得標籤*/
int rgAmount = numberPicker.getValue();
ArrayList<String> rgLabel = new ArrayList<>();
for (int i = 0; i < rgAmount; i++) {
rgLabel.add("第" + (i + 1) + "項目");
}
Log.d(TAG, "setRadioAction: "+rgLabel);
}
看一下Logcat:
可以看見我們標籤項目有四個了
再來就是加入介面及方法
/**
* 設置主畫面上的RadioButton
*/
private void setRadioAction(NumberPicker numberPicker) {
/*取得標籤*/
int rgAmount = numberPicker.getValue();
ArrayList<String> rgLabel = new ArrayList<>();
for (int i = 0; i < rgAmount; i++) {
rgLabel.add("第" + (i + 1) + "項目");
}
Log.d(TAG, "setRadioAction: "+rgLabel);
/*根據標籤數量設置幾個RadioButton*/
LinearLayout layoutMain = findViewById(R.id.linearLayout_Main);
RadioGroup radioGroup = new RadioGroup(this);
radioGroup.setOrientation(RadioGroup.VERTICAL);
layoutMain.removeAllViewsInLayout();
RadioGroup.LayoutParams rlTable;
}
在這邊要特別注意反綠的部分一定要加,不然最後出現結果會這樣
無限增加...(´ж`;)
最後是將RadioButton放進RadioGroup的部分
然後迴圈外就是把RadioGroup放入layout內
/**
* 設置主畫面上的RadioButton
*/
private void setRadioAction(NumberPicker numberPicker) {
/*取得標籤*/
int rgAmount = numberPicker.getValue();
ArrayList<String> rgLabel = new ArrayList<>();
for (int i = 0; i < rgAmount; i++) {
rgLabel.add("第" + (i + 1) + "項目");
}
Log.d(TAG, "setRadioAction: "+rgLabel);
/*根據標籤數量設置幾個RadioButton*/
LinearLayout layoutMain = findViewById(R.id.linearLayout_Main);
RadioGroup radioGroup = new RadioGroup(this);
radioGroup.setOrientation(RadioGroup.VERTICAL);
layoutMain.removeAllViewsInLayout();
RadioGroup.LayoutParams rlTable;
for (int i = 0; i < rgLabel.size(); i++) {
RadioButton radioButton = new RadioButton(this);
radioButton.setText(rgLabel.get(i));
rlTable = new RadioGroup.LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT
, RadioGroup.LayoutParams.MATCH_PARENT);
radioGroup.addView(radioButton, rlTable);
}
layoutMain.addView(radioGroup);
}
Ok,到此為止程式就完成了( ゚Д゚)b
按下執行看一下吧~
3.加入點擊事件
接著我們要為RadioButton加入點擊事件
目標是要點擊後取得兩項資訊-RadioButton的內容以及其代表的position(在Group內的Id)
而對應其點擊的方法就是setOnCheckedChangeListener方法
直接上程式
lambda表示法:
radioGroup.setOnCheckedChangeListener(((group, checkedId) -> {
}));
一般表示法:
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
}
});
哇!真貼心!回傳checkId耶(゜ロ゜)
這樣是不是只要標籤陣列"rgLabel"然後rgLabel.get(checkedId
);就大功告成了呢?
廢話,我會這樣講,表示肯定有詐
我們來觀察一下checkId會回傳什麼
OK執行開始(-ω-ゞ
首先轉輪到五,然後點擊第四選項
恩看起來沒問題
再來點3
好,OK
點1
再來轉輪切到3組,按下顯示,然後點擊第三項目
恩?
花!惹!發?
之前第一次遇到問題時這是我心中第一個想法....
好啦既然我會PO表示解決了(∩╹□╹∩)
這時候我是搜尋CSDN論壇,keyWord為
RadioGroup.OnCheckedChangeListener checkedId累加
我直接說結論
結論是這算是這個套件的小Bug之一
如果一直重新載入的話,就會造成ID一直累加
因此我翻了好久官網文件才找到方法
好在RadioButton有提供一種方法叫做getCheckedRadioButtonId()
他是可以幫助你標示出你選中的RadioButton其對應的xml ID
於是我們先新增一個RadioButton,然後逆向操作從其ID身上獲取資訊就可以了
其次兩行也順便講,取得到該RadioButton後,就可以再進一步取得他對應於Group內的ID以及他標籤的名稱
如此這般如此這般~這樣就完成囉!
radioGroup.setOnCheckedChangeListener(((group, checkedId) -> {
RadioButton radioButton = findViewById(group.getCheckedRadioButtonId());
String getLab = radioButton.getText().toString();
int getGroupId = group.indexOfChild(radioButton);
Toast.makeText(this, getLab + ", id=" + getGroupId, Toast.LENGTH_LONG).show();
}));
另外提醒,在回傳中的group其實就是回傳RadioGroup本身
因此就算沒有這個override,一樣可以獲取到標籤的相關資訊喔
4.套入到Dialog內
套入到AlertDialog內的方法大同小異,並沒有別的不同
我直接上程式,用標注的方法來講解吧
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName() + "My";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btDisplay = findViewById(R.id.button_display);
Button btDialog = findViewById(R.id.button_showDialog);
NumberPicker numberPicker = findViewById(R.id.numberPicker);
numberPicker.setMaxValue(5);
numberPicker.setMinValue(1);
btDisplay.setOnClickListener((v) -> {
setRadioAction(numberPicker);
});
btDialog.setOnClickListener(v -> {
setDialogRadioAction(numberPicker);
});
}//End onCreate
/**
* 設置Dialog上的RadioButton
*/
private void setDialogRadioAction(NumberPicker numberPicker) {
/*取得標籤*/
int rgAmount = numberPicker.getValue();
ArrayList<String> rgLabel = new ArrayList<>();
for (int i = 0; i < rgAmount; i++) {
rgLabel.add("第" + (i + 1) + "項目");
}
/*設置AlertDialog以及內容物*/
AlertDialog.Builder mBuilder = new AlertDialog.Builder(this);
View view = getLayoutInflater().inflate(R.layout.choose_dialog, null);
mBuilder.setView(view);
/*根據標籤數量設置幾個RadioButton*/
LinearLayout layoutDialog = view.findViewById(R.id.linearLayout_Dialog);
RadioGroup radioGroup = new RadioGroup(this);
radioGroup.setOrientation(RadioGroup.VERTICAL);
layoutDialog.removeAllViewsInLayout();
RadioGroup.LayoutParams rlTable;
for (int i = 0; i < rgLabel.size(); i++) {
RadioButton radioButton = new RadioButton(this);
radioButton.setText(rgLabel.get(i));
rlTable = new RadioGroup.LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT
, RadioGroup.LayoutParams.MATCH_PARENT);
radioGroup.addView(radioButton, rlTable);
}
layoutDialog.addView(radioGroup);
/*設置點擊事件*/
mBuilder.setNegativeButton("取消", null);
mBuilder.setPositiveButton("OK", (dialog, which) -> {
try {
RadioButton radioButton = view.findViewById(radioGroup.getCheckedRadioButtonId());
String getDialogLab = radioButton.getText().toString();
int getDialogId= radioGroup.indexOfChild(radioButton);
Toast.makeText(this, getDialogLab + ", id=" + getDialogId, Toast.LENGTH_LONG).show();
}catch (Exception e){
Toast.makeText(this, "未點選任何項目", Toast.LENGTH_LONG).show();
}
});
mBuilder.show();
}
}
藍色部分是關於AlertDialog的設置
唯一需要注意的是,所有呼叫findViewById的部分,都記得要加入"view.findViewById"(有粗體標註)
否則程式會出錯喔!
至於對於AlertDialog不熟的朋友,可參考
這篇->http://thumbb13555.pixnet.net/blog/post/310777160
希望對你有幫助~
結論
首先補上可直接copy走的副程式
/**直接複製區域*/
private void copy(int amount,LinearLayout layout){
ArrayList<String> rgLabel = new ArrayList<>();
for (int i = 0; i < amount; i++) {
rgLabel.add("第" + (i + 1) + "項目");
}
/*根據標籤數量設置幾個RadioButton*/
RadioGroup radioGroup = new RadioGroup(this);
radioGroup.setOrientation(RadioGroup.VERTICAL);
layout.removeAllViewsInLayout();
RadioGroup.LayoutParams rlTable;
for (int i = 0; i < rgLabel.size(); i++) {
RadioButton radioButton = new RadioButton(this);
radioButton.setText(rgLabel.get(i));
rlTable = new RadioGroup.LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT
, RadioGroup.LayoutParams.MATCH_PARENT);
radioGroup.addView(radioButton, rlTable);
}
layout.addView(radioGroup);
/*設置點擊事件*/
/*點擊並獲取標籤內容與"真正的"ID*/
radioGroup.setOnCheckedChangeListener(((group, checkedId) -> {
RadioButton radioButton = findViewById(group.getCheckedRadioButtonId());
String getLab = radioButton.getText().toString();
int getGroupId = group.indexOfChild(radioButton);
Toast.makeText(this, getLab + ", id=" + getGroupId, Toast.LENGTH_LONG).show();
}));
}
傳入值為: copy(int 多少個RadioButton, LinearLayout 放置RadioGroup的Layout)
copy(numberPicker.getValue(),findViewById(R.id.linearLayout_Main));
RadioButton不算是太難的元件
但是要設計得可以自由增減也是要花一定的功夫處理
我之前在網路搜集相關資料時基本上還是以大陸的CSDN跟英文搜尋結果為主
希望看到這裡的你,能夠正常的運作今天的功能
留言列表