安卓 RecyclerView局部刷新

 

 

  在我们的开发中,RecyclerView是使用非常频繁的,除了常用的列表展示之外,很多时候我们要根据item的操作进行列表的刷新,比如勾选列表的勾选、删除或者根据操作动态设置某个item的布局。这时候,大部分人包括我在内使用的都是这种方式:修改数据源list,然后调用adapter的notifyDataSetChanged()进行刷新。

   这种方式是我们经常采用的,在数据量比较小或者大部分的场景下都是适用的。但是这种方式却是最浪费性能的,只在少部分情况下合适。很多情况下并不合适,比如一个勾选列表,我们进行多选的时候,如果每选一次就进行一次notifyDataSetChanged,相当于因为针对一个item的操作而刷新整个列表中所有的item,这对于RecyclerView的性能是种损害,也不够聪明,通过缓存勾选状态的数据,我们可以使用全局刷新的方式完成想要的结果,但这不是最佳的方式,人都要有点追求,代码也一样。我们可以使用局部刷新的方式,为什么要进行全局刷新?

   而RecyclerView的本身就为我们提供了局部刷新的方式,在adpter中,有这个方法,它跟我们常用的onBindViewHolder很像,只是多了一个参数,我们就是利用这个参数实现局部刷新的功能,这个参数就是最后面的payloads

public void onBindViewHolder(VHholder, int position, List<Object> payloads) {
            onBindViewHolder(holder, position);
        }

因为这个方法多了一个payloads,而且它会在我们不仅可以利用这个payloads进行逻辑判断,还能传参,它是List<Object>类型的数据,这可以说说是我们最方便使用的数据类型,我们可以往里面放我们的任何类型的数据,从对象到字符串、布尔值、整型或者对象集合等。
  而这个带payloads的onBindViewHolder会在触发notifyItemChanged(int position, @Nullable Object payload)方法后调用,这个方法我们通过英文也能知道,是刷新指定position的item,并且可以传递一个object类型的payloads参数。
拿我实际的项目需求举例,  
                               
如上图,item的下方有一个按钮“收起课表”(”展开课表“),我们的需求是在点击”展开课表“时候进行再接口请求,获取那些第几讲的数据(别问为什么不一次请求完所有数据,就是这个需求),然后课表要有展开的动画(这个动画我个人感觉可以再写个博客,哈哈),这就需要我进行item的局部刷新,那么如何刷新?
     当点击”展开课表"的接口的时候,回调activity中的接口调用,然后再接口中做完数据的安全判断后只需要一行代码courseArrangementListAdapter.notifyItemChanged(unFoldItemPosition, baseResult.getResultData());
  notifyItemChanged第一个参数是要刷新的item的position,这个方法的第二个参数,就是onBindViewHolder(VHholder, int position, List<Object> payloads)的payloads,我把课表数据也就是payload传过去,在onBindViewHolder中如下,通过对payload进行判断以及取值,就可以只对position=unFoldItemPosition的item进行处理。
我在不带payloads的onBindViewHolder中处理普通的业务处理,而在带payloads的onBindViewHolder中进行刷新处理。
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull List<Object> payloads) {
    super.onBindViewHolder(holder, position, payloads);
    PlanListEntity.RowsBean bean = list.get(position);

    if (payloads.isEmpty()) {
        LogUtils.d("=========", "onBindViewHolder payload isEmpty ");
        onBindViewHolder(holder, position);
    } else {
        LogUtils.d("=========", "onBindViewHolder payload: " + payloads);
        List<CoursePlanTimetableEntity> timetableEntityList = (List<CoursePlanTimetableEntity>) payloads.get(0);
        if (timetableEntityList.size() > 0) {
            handleTimeView(timetableEntityList, holder);
        }
        if (holder.tvTimetableAction.getText().toString().equals(context.getString(R.string.fold_timetable))) {
            //展示展开课表动画
            showTimetableUnfoldAnimator(timetableEntityList, holder);
        } else {
            //展示收起课表动画
            showTimetableFoldAnimator(timetableEntityList, holder);
        }
    }
}
很简单但是很实用,希望能帮助到看到这篇博客的朋友。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章