在上一年的時候我曾經寫了一篇<<在RecyclerView中實現定點刷新>>的文章介紹瞭如何使用DataBinding框架進行局部刷新。時隔將近一年,期間我也換了一份工做,在新公司裏並無使用到DataBinding,因此若是想進行局部刷新ui,可能須要使用較早的adapter.notifyItemChanged(pos)
。git
近期在作一個功能的時候,發現有一個比較簡即可行的方法,能夠達到局部刷新的效果。github
其實思考🤔一下,若是要更新一個TextView的文本,須要怎麼作呢?編程
答案很是簡單:那就是找到這個TextView,而後調用它的setText
方法。markdown
代碼的話,多是這樣 :框架
findViewById<TexView>(R.id.titleTv).text = "title" 複製代碼
上面的是指普通的View,那麼在RecyclerView呢?oop
其實答案差很少,咱們只須要找到對應的ItemView
或者它的ViewHolder
,而後調用對應的渲染ui的方法就好了。先看看效果:post
那應該怎麼作呢?優化
其實RecyclerView
已經提供了根據position
獲取ViewHolder
這個功能。ui
從方法裏能夠看到RecyclerView
會for循環去找holder,而後比較位置,若是不爲null,且沒有被移除,那麼表明能夠找到了,反之則爲null。this
其中childCount
是經過 this.mChildHelper.getUnfilteredChildCount()
獲得的。
其最終會調用RecyclerView的getChildCount()
方法,返回的結果表示可見的item個數。好比當前可見的是8個,那麼childCount便是8,因此你想獲取超過屏幕最大Index的ViewHoler,那麼就會返回null。好比當前最大可見的position爲13,若是你想找第11個,可以獲取到,可是找第15個,那麼會返回null。
接着咱們來拆解獲取ViewHolder的方法,以下所示:
getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i)); 複製代碼
首先會經過getUnfilteredChildAt
獲取到index對應的view。這個方法最後也是調用的RecyclerView的getChildAt(offset)方法。
找到View以後,再用getChildViewHolderInt(view)
獲取對應的ViewHolder,其內部實現以下:
即經過LayoutParams
獲取到相應的ViewHolder。
而將ViewHolder賦值給LayoutParams的過程出如今RecyclerView的getViewForPosition(pos)
方法中,最終會被LayoutManager調用。
回到主題,如今咱們獲取到了想要的ViewHoler
,並且也知道了當前的Position
,那麼只須要再調用Adapter的
onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
便可。
固然由於在Adapter中也能獲取到RecyclerView,因此能夠將更新的方法放入到Adapter中。
數據變化的時候,調用notifyItemUpdate(pos:Int)
便可,能夠說是很簡單了。
若是要說再優化的話,固然也有繼續優化的點,好比減小無用的更新,或者說能在子線程通知更新UI,固然這些都是後話,之後再來完善。
GitHub示例:github.com/ditclear/Bi…
==================== 分割線 ======================
若是你想了解更多關於MVVM、Flutter、響應式編程方面的知識,歡迎關注我。
你能夠在如下地方找到我:
簡書:www.jianshu.com/u/117f1cf0c…
Github: github.com/ditclear