iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 26
0
自我挑戰組

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

Day 26 ─用 Kotlin 做待辦清單 Todolist(9) DatePickerDialog 及新增資料屬性(下)

  • 分享至 

  • xImage
  •  

讓 Todolist 功能更多元,使用者可以輸入待辦事項的標題、內文及日期,這些內容可以在返回主頁之後,點擊跳出一個對話框檢視,簡單來說要做的事有:

  • 新增待辦事項內容 EditText、日曆按鈕 ImageView 和用來顯示日期的 TextView(✓)
  • 修改 Thing 資料型態的屬性
  • 儲存進 Sharepreference 的東西變多
  • 為 RecycleView 每項 item 都設定點擊事件,會跳出對話框
  • 對話框會顯示新增的內容及日期

昨天完成了第一項,練習 DatePickerDialog 讓使用者可以選日期,現在待辦清單和之前版本有了很大變化,多了一個待辦事項的內容、一個日期字串,這些新加入的東西也是資料一部分,所以現在要來修正資料型態。

一、修改 Thing 資料型態

data class Thing(
    val key: String,        //原本的 Key 值
    var title : String,     //原本的 todo 字串,改成待辦事項-標題
    var content : String,   //新增待辦事項-內容
    var date : String,      //新增待辦事項-日期
    var isSelected :        //原本的 isSelected 布林值
    Boolean = false
)

二、Sharepreference 儲存新增資料(Main2Activity.kt)

==function save()==

函式 save() 有設條件,區分出編輯模式和新增模式,這裡先修改新增模式的部分:

  1. 宣告一個 todo 變數,是 Thing 這種資料型態
  2. 把使用者輸入的資料放入 todo
  3. 將 todo 用 Gson() 包成字串符 todoJson
  4. 儲存進 Sharepreference 裡,todoJson 作為 putString(Key, Value) 的 Value 值
var i = 0
    while (!sharedPreferences.getString("todo-${i}", "").isNullOrEmpty()){
        i++
    }                   //Key值     //待辦事項-標題        //待辦事項-內容       //待辦事項-日期
    val todo = Thing("todo-${i}", "${ed_title.text}", "${ed_content.text}", "${tv_date.text}")
    val todoJson = Gson().toJson(todo)   //包成Json()字串符
    editor.putString("todo-${i}", todoJson).apply()

檢查一下,確認有沒有存入全部資料

三、從 Sharepreference 讀到資料(MainActivity.kt)

==function getEvent()==

因為資料儲存時被轉成 Json() 字串符,取資料的時候要把它轉回來、放入 things 陣列裡

  1. 註解掉之前的 code
  2. 索引 key 值取得字串符
  3. 轉換 Json(),參考 Gson.fromJson 的使用 (Kotlin)
  4. 取到資料放入 things 陣列
// for(key in todolist){
//     val thing = Thing(key, sharedPreferences.getString(key, "")!!)
//     things.add(thing)      //將Thing兩個性質都取得
// }
    
for(key in todolist){
    val todoJson = sharedPreferences.getString(key, "") 
    val todo = Gson().fromJson(todoJson, Thing::class.java)
    things.add(todo)
}      

四、為 RecycleView 每項 item 設定點擊事件(MyAdapter.kt)

設定點擊功能已經寫過了,可在 Day 20 ─給 RecyclerView Item 添加點擊事件複習是如何運用,繼續在 interface 新增一個 toShow() 方法,讓物件的點擊事件可以和 interface 這個方法連結,以便於從外部呼叫:

綁定 RecyclerView 畫面元件
呼叫 ViewHolder 建構式,必須提供 RecyclerView 其中一個選項的View,像是下方程式碼綁定的 tv_todoimg_editchk_delete 等等,這樣才能對他們做點擊事件

inner class ViewHolder(v: View):RecyclerView.ViewHolder(v){
    val tv_todo = v.findViewById<TextView>(R.id.tv_todo)
    val img_edit = v.findViewById<ImageView>(R.id.img_edit)
    val chk_delete = v.findViewById<CheckBox>(R.id.chk_delete)
    
    fun bind(thing: Thing){
        tv_todo.setText(thing.title)
        img_edit.setOnClickListener{...}
        chk_delete.isChecked = thing.isSelected
        chk_delete.setOnClickListener{...}
    }
}

直接呼叫整個 itemView 對其做點擊事件:這樣無論使用者點到 item 哪各部分,都會作用

Public constructors
RecyclerView.ViewHolder(View itemView)
itemView.setOnClickListener {
    itemClickListener?.toShow(thing)
}

五、點擊 item 實作 AlertDialog(MainActivity.kt)

一樣在 MainActivity 裡面會被要求 override 方法 toShow(),讓它執行函式 ShowEvent()

override fun toShow(event: Thing) {
    ShowEvent(event)
}

==function ShowEvent()==

函式 ShowEvent() 要執行的是跳出 AlertDialog 對話框,顯示資料的標題、內容、日期和一個確認按鈕,之前寫過 Day 6 ─用Kotlin做點餐介面 (4) AlertDialog,複習一下來做:

  • 自定義參數 event 是 Thing 資料型態
  • 那就可以取得 Thing 的屬性,.title.content.date 等等
  • 最後不要忘記 .show() 顯示出來
private fun ShowEvent(event: Thing){
    AlertDialog.Builder(this)
        .setTitle("待辦事項:${event.title}")
        .setMessage("內容: ${event.content}\n日期: ${event.date}")
        .setPositiveButton("確認"){dialog, which ->
                dialog.cancel()
        }
        .show()
}

六、編輯模式下讀取資料(Main2Activity.kt)

修改資料,從主頁跳到第二頁的編輯模式,是利用 startActivityForResult(intent, 1) 夾帶資料及記錄返回點。到了編輯頁面後,和之前一樣同樣顯示原本的文字或日期,於是:

title = "編輯模式"
val eventEdit = intent.getStringExtra("event")
val event = Gson().fromJson(eventEdit, Thing::class.java)
//     eventKey = event.key     註解掉之前的 code
//     editText = event.todo
eventKey = event.key                  //取得 key 值
ed_title.setText(event.title)         //取得標題
ed_content.setText(event.content)     //取得內容
tv_date.text = event.date             //取得日期

唯一美中不足的是,點選日曆按鈕時會顯示當前時間,而不是顯示之前指定的時間,因為我們設定 calendar.get(Calendar.time,有點懶得改了哈哈,有機會再補充
)


上一篇
Day 25 ─用 Kotlin 做待辦清單 Todolist(8) DatePickerDialog 及新增資料屬性(上)
下一篇
Day 27 ─如何修改 Application Icon
系列文
Kotlin Everyday:新手寫程式踩的坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言