文章目录
一、修改单条数据
二、批量修改数据
三、完整代码示例
四、RecyclerView 相关资料
一、修改单条数据
修改单条数据 : 调用 RecyclerView.Adapter 的 void notifyItemChanged(int position) 方法 , 传入的参数是被删除元素的索引 ( 删除之前的索引值 ) ;
该方法的作用是通知任何被注册的观察者 , position 位置的 item 元素对应的数据被修改了 ;
该方法等价于 notifyItemChanged(position, null) ;
int position 参数 : 发生改变的 item 元素位置 ;
注意 : 调用该方法后 , 只会刷新与该位置相关的 item 元素 , 不会刷新其它元素 , 即使数据改变了 , 也不会刷新 ; 也就是说 RecyclerView 只刷新涉及到的 position 位置的元素 , RecyclerView 中的其它 item 元素不变 ; position 位置的元素身份 id 不变 , 只是绑定的数据发生改变 ;
代码示例 : 修改第 0 00 个元素 ;
// 替换第 0 个元素 names.set(0, "宋江江"); // 通知适配器 adapter.notifyItemChanged(0);
RecyclerView.Adapter.notifyItemChanged(int position) 函数原型 : 该函数定义在 RecyclerView 的内部类 Adapter 中 ;
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild2, NestedScrollingChild3 { public abstract static class Adapter<VH extends ViewHolder> { /** * 通知任何被注册的观察者 , position 位置的 item 元素对应的数据被修改了 ; * 该方法等价于 notifyItemChanged(position, null) ; * * 这是一个结构性的变化事件 ; * 表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 , * 尽管它们的位置已经发生了变化 ; * 也就是说 RecyclerView 只刷新涉及到的 positionStart ~ positionStart + itemCount 之间的这几个元素 , * 其它元素不变 ; * position 位置的元素身份不变 , 只是绑定的数据发生改变 ; * * @param position 发生改变的 item 元素位置 * * @see #notifyItemRangeChanged(int, int) */ public final void notifyItemChanged(int position) { mObservable.notifyItemRangeChanged(position, 1); } } }
运行效果 : 动画效果是系统自带的 , 可以自己实现 ;
二、批量修改数据
批量修改数据 : 调用 RecyclerView.Adapter 的 void notifyItemRangeRemoved(int positionStart, int itemCount) 方法 , 传入的参数是被修改的元素的首个索引 , 以及插入元素的个数 ;
该方法的作用是通知任何被注册的观察者 , 从 positionStart 位置开始的的 itemCount 个 item 元素对应的数据已经被修改 ;
该方法等价于 notifyItemRangeChanged(position, itemCount, null) ;
参数说明 :
int positionStart 参数 : 被修改的元素在原数据集中首个元素的位置索引 ;
int itemCount 参数 : 数据集中被修改元素个数 ;
注意 : 这是一个结构性的变化事件 ;
表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 , 尽管它们的位置已经发生了变化 ;
也就是说 RecyclerView 只刷新涉及到的 positionStart ~ positionStart + itemCount 之间的这几个元素 , 其它元素不变 ;
此外这些位置的元素身份不变 , 只是绑定的数据发生改变 ;
代码示例 : 修改前 3 33 个数据 , 通知适配器 ;
// 替换第 0, 1, 2 个元素 names.set(0, "宋江江"); names.set(1, "卢俊俊"); names.set(2, "吴用用"); // 通知适配器 adapter.notifyItemRangeChanged(0, 3);
RecyclerView.Adapter.notifyItemInserted(int position) 函数原型 : 该函数定义在 RecyclerView 的内部类 Adapter 中 ;
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild2, NestedScrollingChild3 { public abstract static class Adapter<VH extends ViewHolder> { /** * 通知任何被注册的观察者 , 从 positionStart 位置开始的的 itemCount 个 item 元素对应的数据已经被修改 ; * 该方法等价于 notifyItemRangeChanged(position, itemCount, null) ; * * 这是一个结构性的变化事件 ; * 表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 , * 尽管它们的位置已经发生了变化 ; * 也就是说 RecyclerView 只刷新涉及到的 positionStart ~ positionStart + itemCount 之间的这几个元素 , * 其它元素不变 ; * 此外这些位置的元素身份不变 , 只是绑定的数据发生改变 ; * * @param positionStart 被修改的元素在原数据集中首个元素的位置索引 ; * @param itemCount 数据集中被修改元素个数 ; * * @see #notifyItemChanged(int) */ public final void notifyItemRangeChanged(int positionStart, int itemCount) { mObservable.notifyItemRangeChanged(positionStart, itemCount); } } }
运行效果 : 动画效果是系统自带的 , 可以自己实现 ;
三、完整代码示例
完整代码示例 仅做参考 :
package kim.hsl.recyclerview; import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.StaggeredGridLayoutManager; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { /** * 数据源 */ private ArrayList<String> names = new ArrayList<String>(); /** * 适配器 */ private Adapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化数据 initData(); //1 . 从布局中获取 RecyclerView RecyclerView recycler_view = findViewById(R.id.recycler_view); //2 . 创建并设置布局管理器 //创建布局管理器 StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager( 4, RecyclerView.VERTICAL); //设置布局管理器 recycler_view.setLayoutManager(layoutManager); // 设置边距 recycler_view.addItemDecoration(new ItemDecoration()); //3 . 创建并设置列表适配器 adapter = new Adapter(); recycler_view.setAdapter(adapter); // 初始化点击事件 initClick(); } /** * 初始化数据 */ private void initData(){ names.add("宋江"); names.add("卢俊义"); names.add("吴用"); names.add("公孙胜"); names.add("关胜"); names.add("林冲"); names.add("秦明"); names.add("呼延灼"); names.add("花荣"); names.add("柴进"); names.add("李应"); names.add("朱仝"); names.add("鲁智深"); names.add("武松"); names.add("董平"); names.add("张清"); names.add("杨志"); names.add("徐宁"); names.add("索超"); } void initClick(){ // 增加单个数据 findViewById(R.id.insert_single).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 在集合开始添加一个元素 names.add(0, "戴宗"); // 通知适配器新元素添加 adapter.notifyItemInserted(0); } }); // 增加多个数据 findViewById(R.id.insert_multi).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 在集合开始添加多个元素 names.add(0, "戴宗"); names.add(0, "刘唐"); names.add(0, "李逵"); // 通知适配器多个新元素添加 adapter.notifyItemRangeInserted(0, 3); } }); // 删除单个数据 findViewById(R.id.delete_single).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 删除第 0 个元素 names.remove(0); // 通知适配器 adapter.notifyItemRemoved(0); } }); // 删除多个数据 findViewById(R.id.delete_multi).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 删除第 0 ~ 2 个元素 names.remove(0); names.remove(0); names.remove(0); // 通知适配器 adapter.notifyItemRangeRemoved(0, 3); } }); // 修改单个数据 findViewById(R.id.modify_single).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 替换第 0 个元素 names.set(0, "宋江江"); // 通知适配器 adapter.notifyItemChanged(0); } }); // 修改多个数据 findViewById(R.id.modify_multi).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 替换第 0, 1, 2 个元素 names.set(0, "宋江江"); names.set(1, "卢俊俊"); names.set(2, "吴用用"); // 通知适配器 adapter.notifyItemRangeChanged(0, 3); } }); // 移动数据 findViewById(R.id.move_single).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 先移除第 0 个 names.remove(0); // 然后在第 7 个位置插入, 此时变为第 7 个元素 names.add(7, "宋江"); // 通知适配器 adapter.notifyItemMoved(0, 7); } }); } /** * RecyclerView 适配器 */ public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> { @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View root_view = LayoutInflater.from(MainActivity.this) .inflate(R.layout.item_recyclerview, parent, false); return new ViewHolder(root_view); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.text.setText("" + names.get(position)); } @Override public int getItemCount() { return names.size(); } public class ViewHolder extends RecyclerView.ViewHolder { TextView text; public ViewHolder(@NonNull View itemView) { super(itemView); text = itemView.findViewById(R.id.text); } } } }
四、RecyclerView 相关资料
官方文档 :
使用 RecyclerView 创建动态列表 : https://developer.android.google.cn/guide/topics/ui/layout/recyclerview
高级 RecyclerView 自定义 : https://developer.android.google.cn/guide/topics/ui/layout/recyclerview-custom
RecyclerView 官方文档 : https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView
RecyclerView.Adapter 官方文档 : https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter
RecyclerView.ViewHolder 官方文档 : https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.ViewHolder
RecyclerView.ItemDecoration 官方文档 : https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.ItemDecoration
代码示例 :
GitHub 源码地址 : https://github.com/han1202012/001_RecyclerView
博客源码快照 : https://download.csdn.net/download/han1202012/14984775
( 使用 Android Studio 打开 )