在上一年的时候我曾经写了一篇<<在RecyclerView中实现定点刷新>>的文章介绍了如何使用DataBinding框架进行局部刷新。时隔将近一年,期间我也换了一份工做,在新公司里并无使用到DataBinding,因此若是想进行局部刷新ui,可能须要使用较早的adapter.notifyItemChanged(pos)
。git
近期在作一个功能的时候,发现有一个比较简即可行的方法,能够达到局部刷新的效果。github
其实思考🤔一下,若是要更新一个TextView的文本,须要怎么作呢?编程
答案很是简单:那就是找到这个TextView,而后调用它的setText
方法。框架
代码的话,多是这样 :post
findViewById<TexView>(R.id.titleTv).text = "title"
复制代码
上面的是指普通的View,那么在RecyclerView呢?优化
其实答案差很少,咱们只须要找到对应的ItemView
或者它的ViewHolder
,而后调用对应的渲染ui的方法就好了。先看看效果:ui
那应该怎么作呢?this
其实RecyclerView
已经提供了根据position
获取ViewHolder
这个功能。spa
从方法里能够看到RecyclerView
会for循环去找holder,而后比较位置,若是不为null,且没有被移除,那么表明能够找到了,反之则为null。线程
其中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