寫在前面
在上一年的時(shí)候我曾經(jīng)寫了一篇<<在RecyclerView中實(shí)現(xiàn)定點(diǎn)刷新>>的文章介紹了如何使用DataBinding框架進(jìn)行局部刷新氛改。時(shí)隔將近一年叁执,期間我也換了一份工作捶码,在新公司里并沒有使用到DataBinding递瑰,所以如果想進(jìn)行局部刷新ui破停,可能需要使用較早的adapter.notifyItemChanged(pos)
陷嘴。
近期在做一個(gè)功能的時(shí)候,發(fā)現(xiàn)有一個(gè)比較簡(jiǎn)便可行的方法摔竿,可以達(dá)到局部刷新的效果。
那么方法是什么呢少孝?
其實(shí)思考??一下继低,如果要更新一個(gè)TextView的文本,需要怎么做呢稍走?
答案非常簡(jiǎn)單:那就是找到這個(gè)TextView袁翁,然后調(diào)用它的setText
方法。
代碼的話婿脸,可能是這樣 :
findViewById<TexView>(R.id.titleTv).text = "title"
上面的是指普通的View粱胜,那么在RecyclerView呢?
其實(shí)答案差不多狐树,我們只需要找到對(duì)應(yīng)的ItemView
或者它的ViewHolder
焙压,然后調(diào)用對(duì)應(yīng)的渲染ui的方法就行了。先看看效果:
那應(yīng)該怎么做呢?
一個(gè)簡(jiǎn)單的方法
其實(shí)RecyclerView
已經(jīng)提供了根據(jù)position
獲取ViewHolder
這個(gè)功能涯曲。
從方法里可以看到RecyclerView
會(huì)for循環(huán)去找holder,然后比較位置野哭,如果不為null,且沒有被移除幻件,那么代表可以找到了拨黔,反之則為null。
那怎么找呢绰沥?
其中childCount
是通過 this.mChildHelper.getUnfilteredChildCount()
得到的篱蝇。
其最終會(huì)調(diào)用RecyclerView的getChildCount()
方法,返回的結(jié)果表示可見的item個(gè)數(shù)徽曲。比如當(dāng)前可見的是8個(gè)零截,那么childCount即是8,所以你想獲取超過屏幕最大Index的ViewHoler疟位,那么就會(huì)返回null瞻润。比如當(dāng)前最大可見的position為13,如果你想找第11個(gè)甜刻,能夠獲取到绍撞,但是找第15個(gè),那么會(huì)返回null得院。
接著我們來拆解獲取ViewHolder的方法傻铣,如下所示:
getChildViewHolderInt(this.mChildHelper.getUnfilteredChildAt(i));
首先會(huì)通過getUnfilteredChildAt
獲取到index對(duì)應(yīng)的view。這個(gè)方法最后也是調(diào)用的RecyclerView的getChildAt(offset)方法祥绞。
找到View之后非洲,再用getChildViewHolderInt(view)
獲取對(duì)應(yīng)的ViewHolder,其內(nèi)部實(shí)現(xiàn)如下:
即通過LayoutParams
獲取到相應(yīng)的ViewHolder蜕径。
而將ViewHolder賦值給LayoutParams的過程出現(xiàn)在RecyclerView的getViewForPosition(pos)
方法中两踏,最終會(huì)被LayoutManager調(diào)用。
回到主題兜喻,現(xiàn)在我們獲取到了想要的ViewHoler
梦染,而且也知道了當(dāng)前的Position
,那么只需要再調(diào)用Adapter的
onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
即可朴皆。
當(dāng)然因?yàn)樵贏dapter中也能獲取到RecyclerView帕识,所以可以將更新的方法放入到Adapter中。
數(shù)據(jù)變化的時(shí)候遂铡,調(diào)用notifyItemUpdate(pos:Int)
即可肮疗,可以說是很簡(jiǎn)單了。
寫在后面
如果要說再優(yōu)化的話扒接,當(dāng)然也有繼續(xù)優(yōu)化的點(diǎn)伪货,比如減少無用的更新们衙,或者說能在子線程通知更新UI,當(dāng)然這些都是后話超歌,以后再來完善砍艾。
GitHub示例:https://github.com/ditclear/BindingListAdapter
==================== 分割線 ======================
如果你想了解更多關(guān)于MVVM、Flutter巍举、響應(yīng)式編程方面的知識(shí)脆荷,歡迎關(guān)注我。
你可以在以下地方找到我:
簡(jiǎn)書:http://www.reibang.com/u/117f1cf0c556
掘金:https://juejin.im/user/582d601d2e958a0069bbe687
Github: https://github.com/ditclear