RecyclerView的局部刷新(notifyItemChanged(int position,Object payload))

局部刷新的方便之处

RecyclerView的刷新可以分为列表重新加载刷新、item刷新、item中局部刷新。对于前两种的刷新,都会是的列表刷新的时候闪烁一下,而后者则看不出列表有任何闪烁,并且,局部刷新能在一定程度上减少不必要的UI绘制渲染。

RecyclerView 数据刷新的几种方式,RecyclerView 真正的布局刷新的正确方式

notifyDataSetChanged() 刷新全部可见的item

notifyItemChanged(int position) 更新列表position位置上的数据可以调用

notifyItemInserted(int position) 列表position位置添加一条数据时可以调用,伴有动画效果

notifyItemRemoved(int position) 列表position位置移除一条数据时调用,伴有动画效果

notifyItemMoved(int fromPosition, int toPosition) 列表fromPosition位置的数据移到toPosition位置时调用,伴有动画效果

notifyItemRangeChanged(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项进行数据刷新

notifyItemRangeInserted(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项批量添加数据时调用,伴有动画效果

notifyItemRangeRemoved(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项批量删除数据时调用,伴有动画效果

效果图

相关代码块

1、调用设配器的不同刷新方式

// 列表刷新
mAdapter.setDatas(mDatas);

// item的整体刷新
mAdapter.notifyItemChanged(Integer.valueOf(mPos));

// item的局部刷新(参数一:item位置,参数二:更改后的数据,参数三:更改item局部数据的位置)
mAdapter.refreshPartItem(Integer.valueOf(mPos), TextUtils.isEmpty(mDataOne) ? mDataTwo :mDataOne,TextUtils.isEmpty(mDataOne) ? 1 : 0);

2、设配器

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerHolder> {

    private Context mContext;
    private final LayoutInflater mInflater;
    private List<String> mDatas;
    private static final String DATA_ONE = "dataOne";
    private static final String DATA_TWO = "dataTwo";

    public RecyclerViewAdapter(Context context) {
        mDatas = new ArrayList<>();
        mContext = context;
        mInflater = LayoutInflater.from(context);
    }

    // 设置列表数据
    public void setDatas(List<String> datas) {
        mDatas.clear();
        this.mDatas.addAll(datas);
        notifyDataSetChanged();
    }

    // 局部刷新item数据
    public void refreshPartItem(int position, String data, int changePos) {
        if (position > mDatas.size() - 1){
            Toast.makeText(mContext, "输入的行数超过当前数据的行数", Toast.LENGTH_SHORT).show();
            return;
        }
        mDatas.set(position, data);
        // 局部刷新的主要api,参数一:更新的item位置,参数二:item中被标记的某个数据
        notifyItemChanged(position, changePos == 0 ? DATA_ONE : DATA_TWO);  // changePos 为0:数据1   为1:数据2
    }

    @NonNull
    @Override
    public RecyclerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.item_recycler, parent, false);
        return new RecyclerHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerHolder holder, int position) {
        holder.dataOne.setText(mDatas.get(position));
        holder.dataTwo.setText(mDatas.get(position));
    }

    // 专门用于更新item的局部数据
    @Override
    public void onBindViewHolder(@NonNull RecyclerHolder holder, int position,
            @NonNull List<Object> payloads) {
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position);
        }
        else {
            for (Object payload : payloads) {
                switch (String.valueOf(payload)) {
                    case DATA_ONE:
                        holder.dataOne.setText(mDatas.get(position));
                        break;
                    case DATA_TWO:
                        holder.dataTwo.setText(mDatas.get(position));
                        break;
                }
            }
        }
    }

    @Override
    public int getItemCount() {
        return mDatas.size();
    }

    public static class RecyclerHolder extends RecyclerView.ViewHolder {
        TextView dataOne, dataTwo;

        public RecyclerHolder(View itemView) {
            super(itemView);
            dataOne = itemView.findViewById(R.id.data_one);
            dataTwo = itemView.findViewById(R.id.data_two);
        }
    }
}

总结

如上效果图所示,当点击item整体刷新的时候,列表的item会闪烁刷新;而局部刷新,列表刷新并不会闪烁。所以,有时候适当调用正确的刷新方式,不仅可以优化交互效果,还能减少不必要的UI渲染,何乐而不为呢!

相关参考链接

再说Android RecyclerView局部刷新那个坑

RecyclerView之更新UI数据的高级用法

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值