iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
0
自我挑戰組

學習 Android Kotlin 隨筆系列 第 12

[ Day 12 ] 是 RecyclerView 清單啊!(一)實作 TODO-List

  • 分享至 

  • xImage
  •  

| RecyclerView

  • TODO LIST

| 前言概念

  • 前言概念

    • 簡單來講,recyclerView 就是一個能夠呈現像是清單列的一種 layout,每個 item 要放怎樣的格式必須要再另外的定義,透過 recyclerViewAdapter 去實作出來。在這個專案裡面,打算實作一個 TODO 清單,可以增加說明文字以及圖片,並且讓新增的這筆資料顯示在 recyclerView 上面,這篇先示範處理顯示文字 TextView 的部分。
    • 連結 | recyclerView 文章參考
      • 文章定義提到,他是一個在有限的螢幕裡頭,放入無限大量的資料的一個 model,它跟 listView 的差別在於,如果有 30 筆資料的話,在 listView 裡面會一次把 30 筆都創出來,但是在 recyclerView 這邊只會叫出當前視窗的數量(假設 4 個),則往下拉的時候它才會再繼續創剩下的 4 個,這樣會使得程式的 loading 低很多,這會使得 performance 提高

| 實作概念

  • recyclerViewAdapter 實作出來

    這是我學習 adapter 的第一個範本,那時就在想,到底什麼叫做 adapter,為何 adapter 要實作那麼多 function?現在回來整理一次筆記時,更能體會它的含義了。程式裡面的資料,要把他們呈現到畫面的這個環節,就需要透過 adapter 去達成,因為每個 layout 都有他呈現的方式(清單式、navigation 的樣式 ... 等等),而只要告訴 adapter 說現在的資料有哪些,以及一些該 layout 定好的規則需要去做填寫 (每個 layout 有可能有不同規則),背後就會自動將資料通通畫到畫面上囉!

    在這個 recyclerViewAdapter 裡面,需要告訴他每個 item 要長怎樣 (需要回傳一個 View.Holder),這是這個 layout 的特性,如果是 BaseAdapter 就不需要做到這件事情。以下是 recyclerViewAdapter 部分程式碼

    private var noteList = mutableListOf<Holder.Datas>()
    
    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): MyViewHolder {
        val view = LayoutInflater.from(viewGroup.context).inflate(R.layout._4_item_note, viewGroup, false)
        return MyViewHolder(view)
    }
    
    override fun getItemCount(): Int {
        return noteList.size
    }
    
    override fun onBindViewHolder(viewHolder: MyViewHolder, position: Int) {
        viewHolder.bind(noteList[position])
    }
    
    class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
        val tvNote = view.tv_note
    
        fun bind(newList: Holder.Datas) {
            tvNote.text = newList.text
        }
    }
    
    fun update(newList: MutableList<Holder.Datas>) {
        noteList = newList
        notifyDataSetChanged()
    }
    

    當資料有變動的時候,記得要呼叫 notifyDataSetChanged ,畫面才會改變唷!

  • 將編輯頁面的資料回傳回主畫面

    這個專案的新增文字清單,是進到一個新的 fragment 裡面做新增並且按送出,才會返回回主清單頁面。在轉換 Activity 裡面可以透過 ActivityResult 去接取別的 Activity 傳進的資料,那 fragment 呢?

    fragment 裡面,是透過 argument 做傳遞的。今天在編輯頁面按下送出的時候,直接把新增的文字做成一個 bundle,塞回給主畫面,這時主畫面再使用 getArguments() 去做接取,就會接到啦!

    • 塞參數
    // At edit fragment
    // 
    val NEW_DATA = "new"
    args.putString(NEW_DATA, view.input_data.text.toString())
    val todoList = fragmentManager!!.findFragmentByTag("todoList")
    todoList!!.arguments = args
    
    • 收參數
    // At main fragment
    
    val NEW_DATA = "new"
    if(arguments != null){
        val newTxt = arguments?.getString(NEW_DATA)
        holderList.add(Holder.Datas(null, newTxt))
        recyclerAdapter.update(holderList)
    }
    

    因為在切回 main 時會進入 onCreateView ,所以上述收參數的部分寫在 onCreateView 即可。

| 實作小泥坑

  • 收不到回傳回來的參數

    一開始我使用了 savedInstanceState 去做接收,但怎麼看都沒有正確地收到參數,很怪,後來才知道應該要使用 getArguments()savedInstanceState 應該是用在 Activity 等級的切換,需要進入 onSavedInstanceState 的那種才算,而這邊因為只是 fragment 的切換,Activity 根本沒有 onDestroy

  • 明明新增了一筆資料,為什麼畫面沒有更新?

    原先以為在 list 後面新增一筆資料之後,畫面就會更新了,但是其實必須要告訴 adapter 說,我現在的資料已經更新了,畫面要重畫一次,而這個動作就是呼叫 notifyDataSetChanged 就可以解決囉!


上一篇
[ Day 11 ] 是 View Pager 啊 (二)InterceptTouchEvent ,父母管得多?
下一篇
[ Day 13 ] 是 RecyclerView 清單啊!(二)實作 TODO-List
系列文
學習 Android Kotlin 隨筆30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言