iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 7
0
自我挑戰組

Kotlin Everyday:新手寫程式踩的坑系列 第 7

Day 7 ─用Kotlin做點餐介面 (4) RadioButton.OnCheckedChangeListener

  • 分享至 

  • xImage
  •  

本來點餐介面這個主題只打算寫三篇,結果練習時剛好有大神經過,幫我看code順手改了一下,有一些心得要記錄,主要是因為我發現訊息內容和bundle夾帶的code都重疊,就自作聰明把他們移到onCreate外面宣告,結果每跑程式就報錯QQ

問了一下才知道是因為EditText、RadioGroup這些都是在有onCreate基礎下才能建立,class跑完就會跑這幾行,但這時候還無法取得元件,才會報錯

onCreate() 參考
您必須實作此方法。系統建立您的 Activity 時會呼叫此方法。 在您的實作中,應該初始化 Activity 的基本元件。 最重要的是,您必須在這裡呼叫 setContentView(),才能定義 Activity 使用者介面的版面配置。

那麼,要怎麼改才好呢?

Step1. 先搞清楚目的是什麼
是要讓Sugar甜度、Ice冰塊的"值"可以被抓取出來,放在AlertDialog訊息內容和bundle夾帶資料裡面,兩者的資料型態都是String字串

  1. 所以先宣告兩個型態為String的變數,分別是iceVolume和sugarVolume
  2. 設成空值或給一個預設值,因為我單選RadioButton按鈕沒有預設選項,所以當使用者沒點選甜度冰塊時,要顯示空白或預設字串

Step2. 取得選項裡面的值
現在,iceVolume和sugarVolume已經有預設字串可以顯示,那麼要如何在點選時(=狀態改變時)取得該RadioButton值呢?

▲ RadioGroup.OnCheckedChangeListener
在單選RadioGroup和多選Checkbox裡面有一個interface可以調用─

onCheckedChanged(group: RadioGroup!, checkedId: Int)
  1. 用於RadioGroup的監聽。
  2. 實作onCheckedChanged()方法中的參數分別為:
  • RadioGroup用於辨別哪一個RadioGroup呼叫此一監聽器
  • checkedId用於確認在此一群組中哪一個RadioButton被圈選,並將其id傳進來,以進行後續的處理動作

由這個方法可以取得RadioGroup裡面被點選的值,大神有教我兩種寫法:

//方法一

RadioGroup_sugar.setOnCheckedChangeListener { _, i ->
    sugarVolume = when(i){     //i代表被選取的RadioButton_id
        R.id.radioButton_sugar4 -> radioButton_sugar4.text.toString()
        R.id.radioButton_sugar3 -> radioButton_sugar3.text.toString()
        R.id.radioButton_sugar2 -> radioButton_sugar2.text.toString()
        R.id.radioButton_sugar1 -> radioButton_sugar1.text.toString()
        else -> "I don't know"
    }              //處理動作是將其按鈕值轉成String字串,傳到sugarVolume裡面
}

第二種寫法很簡潔,不過對我太簡潔了XD需要時間去吸收理解

RadioGroup_ice.setOnCheckedChangeListener { _, i ->
    iceVolume = radioGroup.findViewById<RadioButton>(i).text.toString()
}             //直接綁RadioButton裡面的id,不用一個一個指定

補充:然後像這種地方其實都可以加一些Log.d讀值,用來檢查程式碼沒有寫錯,或是用Toast元件,除了自己檢查外也可以用來提醒使用者點取到的選項:

//小撇步1
Toast.makeText(this,sugarVolume,Toast.LENGTH_SHORT).show()
//小撇步2
Log.d("Sugar", sugarVolume)

Step3. 修改訊息內容及夾帶資料
現在iceVolume和sugarVolume寫好了,確定狀態變動時、值也會跟著變,只需要把他們填到AlertDialog訊息內容和bundle夾帶資料裡面就好:

.setMessage("訂購人:$name\n飲料名稱:$drinks\n" +
            "甜度:$sugarVolume\n" +
            "冰塊:$iceVolume")
val bundle = Bundle()
bundle.putString("drinks", ed_drinks.text.toString())
bundle.putString("sugar", sugarVolume)
bundle.putString("ice", iceVolume)

還有一個地方可以修改的,就是bundle裡面放的drinks,雖然可以用 ed_drinks.text.toString() 取得,但我們明明在onCreate裡已經給drinks賦值了,

btn_send.setOnClickListener {
    val drinks = ed_drinks.text.toString()
    ...
}

那要怎麼樣才能在拉出去寫的function back調用呢?理想情況如下:

fun back() {
    val bundle = Bundle()
    bundle.putString("drinks", drinks) //理想情況
    bundle.putString("sugar", sugarVolume)
    ...
}

實際上會發生......

其實只要新增一個參數,把drinks丟進函式back就可以做到

  1. 在.setPositiveButton處理的back函式,輸入drinks
  2. 會顯示紅底是因為在function back裡面找不到這個參數
  3. 滑鼠按紅底,alt+enter把參數新增進來
  4. 外面的function back就會自動調用drinks囉

是不是改一改更清楚明瞭呢!


上一篇
Day 6 ─用Kotlin做點餐介面 (4) AlertDialog
下一篇
Day 8 ─用Kotlin RecycleView做一個ImageList (上)
系列文
Kotlin Everyday:新手寫程式踩的坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言