iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 22
0
自我挑戰組

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

Day 22 ─用 Kotlin 做待辦清單 Todolist(5) 區分新增及編輯模式

前天做出 RecycleView Item 點擊效果,不少地方要繼續調整,像是區分新增模式和編輯模式,兩者共用一個頁面,但一個是重新建立一筆資料、另一個則是在舊有的資料進行文字修改,設定跳到編輯模式時 EditText 顯示要修改的文字,所以今天的重點:

  • 第二個頁面時,判斷現在是什麼模式
  • 編輯模式時 EditText 顯示要修改的文字
  • 如何確定資料沒有存錯(即存回 Sharepreference 有確實修改到內容文字)

因為程序有點複雜,所以會一步步來講解,可能比較囉嗦,前天寫到切換頁面時將資料轉成 Json,用 intent 夾帶傳送過去:

如何使用 Gson

提供了 fromJson() 和toJson() 兩個直接用於解析和生成的方法,前者實現反序列化,後者實現了序列化,只需要簡單一行就可以將 Java 對象轉成 Json 字符串。

先在Gradle裡加入,記得同步,這樣等下就可以直接 import

dependencies {
    compile 'com.google.code.gson:gson:2.2.4'
}

將要夾帶資料轉成 Json 字符串後,放入 intent (MainActivity.kt)

fun EditEvent(event: Thing){
    val intent = Intent(this, Main2Activity::class.java)
    val eventString = Gson().toJson(event)    //轉換成 Json 丟入 intent裡
    intent.putExtra("event", eventString)
    startActivityForResult(intent, 1)
}

待會從編輯模式取資料時,再 fromJson() 反序列化,得到原來的字串 (Main2Activity.kt)

val eventString = intent.getStringExtra("event")
val event = Gson().fromJson(eventString, Thing::class.java)
editText.setText(event.todo)  //讓editText顯示 Thing(資料型態)的 todo 內容

了解 Gson 之後,要開始做區分編輯模式和新增模式的頁面(Main2Activity.kt):

  1. 首先定義模式 isEditMode,預設是新增模式(False)
class Main2Activity : AppCompatActivity() {
    private var isEditMode = false
  1. 在 onCreate 設定 if 條件,如果跳轉到這個頁面時夾帶 的 intent 不為空時,判斷為編輯模式isEditMode== True),並且取 intent 資料內容:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main2)
    title ="待辦事項"  

    if (!intent.getStringExtra("event").isNullOrEmpty()){
        isEditMode = true
        title = "編輯模式"              //Activity 標題可以修改
        val eventString = intent.getStringExtra("event") //取得資料內容
        val event = Gson().fromJson(eventString, Thing::class.java)
        
        editText.setText(event.todo)   //讓 editText呈現資料內容(todo)
    }
}

這樣點擊編輯的圖示,跳到第二個頁面時就會

  • EditText 顯示要被修改的內容
  • 頁面標題會是「編輯模式」而非新增待辦事項

順利切換第二頁且夾帶資料,接下來要修改的就是儲存內容並且返回第一頁,因為 EditText 已經顯示出原有字樣,我們直接改掉輸入字再儲存就可以,關鍵是 如何確定這筆資料在 Sharepreference 會被修改到

我們必須取得每筆資料一個不會變動的值,像是身分證一樣可以確認身分的東西,不管顯示的外表或內容怎麼修改,可以讓人辨別是哪筆資料的,那就是--- Key 值
取得 Key 值至關重要,如果沒有特別說明,你點選確認按鈕之後是會被儲存成新的一筆資料,於是,我們要為 Thing 這個資料型態新增一項屬性:

data class Thing(val key: String, var todo: String)   //另把 todo 改為變數(var)供修改
  • 因為資料型態改變了,最好把之前的舊資料先刪掉
    ∴ 因為他們只有一項 todo 屬性
  • 然後也要去 MainActivity 讀取 Sharepreference 的地方做修正
    ∴ 要讓它兩個性質都讀的到,才可以在跳轉編輯模式 intent 裡取到夾帶的 Key 值
fun getData(){
    val sharedPreferences = getSharedPreferences("save", Activity.MODE_PRIVATE)
    things.clear()
    val todolist = sharedPreferences.all.keys.sorted()
    
    // for(todo in todolist){     註解掉
    // things.add(Thing(sharedPreferences.getString(todo, "")!!))
    // }
    
    for(key in todolist){
        val thing = Thing(key, sharedPreferences.getString(key, "")!!)
        things.add(thing)      //將Thing兩個性質都取得
    }
    Myadapter.notifyDataSetChanged()
}
  1. 新增 Key 值之後,就可以用它來釘住要修改的 Sharepreference 資料,先在 Main2Activity 定義一個 eventKey,預設為空
class Main2Activity : AppCompatActivity() {
    private var isEditMode = false
    private var eventKey = ""
  1. 編輯模式isEditMode== True)取 intent 時順便把 Key 值取得,這時候可以看到用 Json() 字符串夾帶資料的好處,只需一行解析資料的全部特性、不用分別取得

val eventString = intent.getStringExtra("event")
val event = Gson().fromJson(eventString, Thing::class.java)

eventKey = event.key            //取得資料 key 值
editText.setText(event.todo)    //取得資料 todo 內容
  1. 上面只設定 eventKey 是資料的 Key 值,它真正的作用是在儲存程式碼裡面,當 isEditMode== True 編輯模式時,儲存的 key 值設為原來那個 Key 值,取代舊的 value

雖然複雜,跟著做幾遍應該就可以理解這幾段程式碼的思路囉~


上一篇
Day21 ─Stetho 超級好用的工具:如何查看 SQLite 和 sharepreference 內資料
下一篇
Day 23 ─用 Kotlin 做待辦清單 Todolist(6) 刪除 Sharepreference 資料 (上)
系列文
Kotlin Everyday:新手寫程式踩的坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言