前言故事
電腦前,小唯不斷地調整程式碼,重複編譯,檢查模擬器上的結果,一整個上午小唯一直在試一個 Android 標籤元件的特效(Tab 特效)- 動態新增新的標籤頁,及移除現有的標籤頁。這問題已經困擾小唯一段時間了,原本以為是個很簡單的效果,一個上午絕對可以搞定,但卻在最後一步,怎麼試效果都不正確,標籤頁雖然可以新增或移除,但標籤頁的內容卻怪怪地。
簡單、或不簡單
小唯要求的規格很簡單,準備一個標籤元件,透過程式的方式,可隨意添加新標籤頁,或移除現有標籤頁(除非只剩下一個標籤頁)。規格聽起來很簡單,小唯心裡盤點著:「需要 TabLayout、ViewPager、FragmentPagerAdapter…」。團隊以往使用標籤元件,常常都是固定數量的標籤頁,只需透過 FragmentPagerAdapter 定義標籤頁數量、標籤名稱、內容等,就能顯示預期的效果:
1 | class UpdatableTabAdapter(fm: FragmentManager): FragmentPagerAdapter( |
但如果要能支援新增刪除,就稍微複雜一點,但只要把固定標籤頁的寫法,改為透過 MutableList 來控制標籤頁的數量,應該也不會太複雜吧:
1 | class UpdatableTabAdapter(fm: FragmentManager): FragmentPagerAdapter( |
結果卻不如預期 😫:
意想不到的解決方案
上述做法是,只要在標籤頁上點選了新增符號,就會在右邊加一個新的標籤頁。反之,點選移除符號則移除最左邊的標籤頁,但怎知移除標籤頁後,卻出現了標籤混亂的狀態,這是因為 FragmentPagerAdapter 保存了標籤頁,並沒有在每次新增移除後都重建標籤頁,即使使用了 notifyDataSetChanged()
結果也是一樣。
經過一個上午的努力,小唯終於找到了關鍵原因,就是在 PagerAdapter 內的 getItemPosition,以下是 PagerAdapter 的內容及說明文件:
1 | /** |
原來 PagerAdapter 的預設是 POSITION_UNCHANGED,這也是告訴自己,這個位置上的內容沒有變喔。小唯立刻在 UpdatableTabAdapter class 中覆蓋這個 function:
1 | override fun getItemPosition(`object`: Any): Int { |
重新編譯,檢查模擬器!結果真如預期,任務達成~ 🎉🎉🎉
相關連結: Demo 專案
------------- 本文结束 下次改用 ViewPager2 吧~ -------------