昨天介紹了 SharedPreferences 用法,並且將傳送 Intent 變成儲存 local storage 的動作,今天就要來把資料讀出來、並且把它放入 RecycleView 裡面:
還記得我們之前有定義 Thing 這種資料嗎?而 things 是存放 Thing 這種型態的陣列
data class Thing(val todo: String) //MyAdapter.kt
private var things = ArrayList<Thing>() //MainActivity.kt
之前我們是把傳過來的資料 getExtras 取得值,把值丟入 things 這個陣列後讓 Adpater 更新畫面,讓值可以在 RecycleView 呈現。
現在全部註解掉,我們要改的是取值的方式---從 SharedPreferences 取值
// val todo = data?.extras?.getString("todo")
// things.add(Thing(todo!!))
// adapter.notifyDataSetChanged() //全部註解掉
寫一個 getData 函式
打開之前儲存時命名 save 的 SharedPreferences 文件,將裡面的內容用 key 值取出來,存為 Thing 這種資料型態,因為之前有定義陣列 things 存放的就是該資料類型,所以把取出來的資料丟給 things 陣列:
data class Thing(val todo: String)
private var things = ArrayList<Thing>()
...
...
fun getData(){
val sharedPreferences = getSharedPreferences("save", Activity.MODE_PRIVATE)
val todo = Thing(sharedPreferences.getString("todo", "")!!)
things.add(todo)
adapter.notifyDataSetChanged()
}
當 function 寫好後,在返回動作和初始時都要執行它,這樣回到主頁的畫面才會更新到:
//返回畫面
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
getData() //返回後也要執行畫面更新
}
}
//初始畫面
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getData() //初始畫面要執行
adapter = MyAdapter(things)
recycleview.layoutManager = LinearLayoutManager(this)
recycleview.adapter = adapter
}
現在做完,一切看起來很完美.....除了一件事!!跳出去 APP 之後,之前寫的值是有存下來,可是只存到了最後一項,這是為什麼呢?
因為儲存的時候,key 值每個都是寫 todo
,一個 key 值只能對應一個 value 值,所以 SharedPreferences 文件的 value 會不停被新的 value 覆蓋,因為他們的 key 值是一樣的
editor.putString("todo", "${editText2.text}")
要想辦法讓 key 值變化,設一個 i 值並用迴圈跑,當儲存資料的次數是未知時,可以使用 while 來判斷:
todo-${i}
--- key值while (條件式) {
迴圈執行的工作
}
var i = 0
while (!sharedPreferences.getString("todo-${i}", "").isNullOrEmpty()){
i++
}
條件設成:當某個 key 值 todo-${i}
對應的 value 不為空時,就執行 i++,白話意思是當這個 todo-${i}
被使用過,就跑下一個 i 來當 key值
fun save(todo: String){
val sharedPreferences = getSharedPreferences("save", Activity.MODE_PRIVATE)
val editor = sharedPreferences.edit()
// editor.putString("todo", "${editText2.text}") 註解掉
var i = 0
while (!sharedPreferences.getString("todo-${i}", "").isNullOrEmpty()){
i++
}
editor.putString("todo-${i}", todo)
editor.apply()
}
修改過的函式 save 放到點擊事件裡,這時系統會顯示紅底、要求我要填一個參數,所以這邊 val 一個值,將 EditText 輸入的東西指給這個參數
else {
// val b = Bundle()
// b.putString("todo", "${editText2.text}")
// val intent1 = Intent()
// intent1.putExtras(b)
val todo = "${editText2.text}"
save(todo)
setResult(Activity.RESULT_OK)
finish()
}
寫完之後查看一下文件 ,可以看到迴圈有跑成功,key 值會照著 todo-${i}
排序下去,確認都有存進本地資料庫裡,明天就要來練習怎麼把這堆 SharedPreferences 資料讀取出來~