iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 23
2

  讓我們把焦點從流程的部分轉回應用程式上,現在第二頁面還缺少一個下一步的按鈕,同時得做一些邏輯驗證,首先在版面上新增一個按鈕及程式上加入點擊的監聽,這些相信難不倒已經學習過之前章節的讀者。

  接著使用 arrayListOf 盛裝,自三個 switch (北極、南極、芬蘭) 讀取的選擇狀態,到這邊可以先試試看使用 println(answer) 查看內容物,接著再使用 lambda 設計我們需要的邏輯:三個至少要選一個。

https://ithelp.ithome.com.tw/upload/images/20181106/20111944yoRULuz5at.png

  這裡使用 any 去判斷集合中是否有任何 true 值,Line: 28 的寫法是 Line: 29 的簡化版,在先前的 Day 11 有相關說明,各位應該可以感覺到,簡化前後以第一直覺去看該行程式碼,哪一段比較能快速理解邏輯條件;又哪一段撰寫起來較迅速簡潔。但是 IDE 會提示你簡化,受不了那條線一直出現在那邊的人應該不少...,採用簡化版本再搭配註解也是個不錯的辦法。

  以下是上圖程式執行成果,在沒選擇的狀況下點按鈕後印出的結果,讀者也可以試試看任選項目後會有什麼不同:

I/System.out: [false, false, false]
    false
    false

  接著把第三頁面加入應用程式中,並且完成邏輯判斷式,可以利用 Toast.makeText() 方法,顯示訊息到螢幕上呈現,第一個參數傳入目前頁面,使用關鍵字 this 即可,第二參數放入想要顯示的文字,如同先前課程提到的,應該採用文字資源管理的方式實作,在這邊的示範為了方便就直接放入文字,第三參數可決定訊息顯示持續的時間,有 Toast.LENGTH_SHORTToast.LENGTH_LONG 兩種可以選擇,分別是 2 秒與 3.5 秒的差別。

https://ithelp.ithome.com.tw/upload/images/20181106/20111944WpWscPyk1R.png

  執行結果如下:

https://ithelp.ithome.com.tw/upload/images/20181106/2011194434I1kcH94u.png


  接著會有一個問題:第三頁面要怎麼知道在第二頁面的選項呢?我們必須設計一個機制將第二頁的值傳送過去,使用 xxx.putExtra() 方法,其中 xxx 是目標頁面,putExtra 可以放入許多型態的資料,這邊我們先用純文字示範。

https://ithelp.ithome.com.tw/upload/images/20181106/20111944nm3TsL8qdd.png

  putExtra() 第一個參數要指定一個 ID,做為取值時的識別,在這邊使用常數的定義方式,讓我們先命名 (規則:全部大寫,以 EXTRA_ 開頭,後面根據常數用途決定)。

https://ithelp.ithome.com.tw/upload/images/20181106/20111944APOOZiIekm.png

  暫時是紅字沒關係,接著到專案總管上新增一個新的 Kotlin File/Class

https://ithelp.ithome.com.tw/upload/images/20181106/20111944S4pc04Yb7i.png

  新增的檔案命名為:ExtraConstants,用來存放所有的 ID,方便管理。

https://ithelp.ithome.com.tw/upload/images/20181106/20111944MovzFpH1av.png

  在新檔案中加入常數字串變數,字串內容也是依據用途決定,只要不重複即可。

https://ithelp.ithome.com.tw/upload/images/20181106/20111944nfC7LiWJdc.png


  此時回到第二頁面就能看到紅字錯誤提示已經消失,接著切換到第三頁面,使用 intent.getStringExtra() 取得剛剛傳入的值,不同的形態會有不一樣的提取使用方法,接著用剛剛介紹過的 Toast 將內容顯示在螢幕上。

https://ithelp.ithome.com.tw/upload/images/20181106/201119442r9Vo7V1lG.png

  成功!正確無誤。

https://ithelp.ithome.com.tw/upload/images/20181106/20111944uO9L1dXziz.png


  但我們的程式是一個 List 型態,要如何傳遞呢?首先必須將整個集合序列化 (Serializable) 轉成 Bundle() 的型態,再將此物件傳送。 Serializable 有其效能上的缺點,文章後段會說明

val extra = Bundle()
extra.putSerializable(EXTRA_AURORA_LIST, answerList)
thirdActivity.putExtra(EXTRA_AURORA_LIST, extra)

  另一個頁面接收時,反向處理,先取出 Bundle 型態,再將之解序列化,並轉型回 ArrayList<Boolean> 格式,讀者可以試著使用 println 印出結果。

var auroraList = intent.getBundleExtra(EXTRA_AURORA_LIST).getSerializable(EXTRA_AURORA_LIST) as ArrayList<Boolean>
println(auroraList)

  在 Run 視窗中,println 出來的值是:I/System.out: [false, true, false],這樣的格式有個缺點:不知道選項到底代表什麼,若要處理這個問題,可以將 arrayList 改為使用 hashMap,所有相關程式調整幅度不大,只有三個地方需要修改,請查看下列兩張截圖的紅框處。

https://ithelp.ithome.com.tw/upload/images/20181106/20111944d5uvqcB5zi.png

https://ithelp.ithome.com.tw/upload/images/20181106/201119448dJWpT1oqO.png


  修改後可以看到 println 的結果變成:I/System.out: {Arctic=false, Antarctic=true, Finland=true},對於後續使用上會比較方便。另外 Serializable 的效能表現其實是有問題的,可以參考這篇文章的比較

https://ithelp.ithome.com.tw/upload/images/20181106/20111944s8m74JFDob.png
圖片來源:https://android.jlelse.eu/parcelable-vs-serializable-6a2556d51538

  在明天的章節會介紹改用 Parcelable方式,搭配使用之前提過的 data class 來進行資料傳遞的乘載。


  額外討論:在所有教學中有用過三種按鈕設定監聽點擊的方法,各位覺得在實作上有什麼優缺點的不同?歡迎大家提出自己的看法,以及會選擇的是哪一個方式。

// 第一種:直接在 onCreate 完成
goBtn.setOnClickListener {
   // Do something
}

// 第二種:透過 layout.xml 鏈結
fun backBtnOnClick(view: View) {
   // Do something
}

// 第三種:在 onCreate 設定一行監聽,呼叫另外獨立的方法
nextBtn.setOnClickListener{ nextBtnOnClick() }

fun nextBtnOnClick() {
   // Do something
}

  那麼今天的教學就到這邊,我們明天見!


資料參考

Toast length long and short 差異
https://stackoverflow.com/questions/7965135/what-is-the-duration-of-a-toast-length-long-and-length-short

Intent putExtra 用於集合
https://stackoverflow.com/questions/18050030/intent-putextra-arraylistnamevaluepair

Parcelable vs Serializable
https://android.jlelse.eu/parcelable-vs-serializable-6a2556d51538

Activity-Android Developers (中文)
https://developer.android.com/guide/components/activities?hl=zh-tw

Kotlin for Android: Beginner to Advanced | Udemy
https://www.udemy.com/devslopes-android-kotlin/

底圖來源
https://pixabay.com/photo-1181004/


上一篇
Day 22. Android Activity Switch - 4/6
下一篇
Day 24. Android Activity 物件傳遞 - 6/6
系列文
Kotlin for Android30

尚未有邦友留言

立即登入留言