【RecyclerView】 十三、RecyclerView 数据更新 ( 移动数据 | 数据改变 )
一、移动数据
移动数据 : 调用 RecyclerView.Adapter 的 void notifyItemMoved(int fromPosition, int toPosition) 方法 , 传入的参数是移动前的位置和移动后的位置 ;
该方法的作用是通知任何被注册的观察者 , fromPosition 位置的 item 元素移动到了 toPosition 位置 ;
参数说明 :
int fromPosition 参数 : 元素移动前的位置 ;
int toPosition 参数 : 元素移动后的新位置 ;
注意 : 这是一个结构性的变化事件 ;
表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 , 尽管它们的位置已经发生了变化 ;
也就是说 RecyclerView 只刷新涉及到的 fromPosition 和 toPosition 这 2 个元素 , 其它元素不变 ;
代码示例 : 先移除第 0 0 0 个元素 , 然后在第 7 7 7 位置插入相同的数据 , 相当于将第 0 0 0 个数据移动到了第 7 7 7 位置 ;
// 先移除第 0 个
names.remove(0);
// 然后在第 7 个位置插入, 此时变为第 7 个元素
names.add(7, "宋江");
// 通知适配器
adapter.notifyItemMoved(0, 7);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
RecyclerView.Adapter.notifyItemMoved(int fromPosition, int toPosition) 函数原型 : 该函数定义在 RecyclerView 的内部类 Adapter 中 ;
public class RecyclerView extends ViewGroup implements ScrollingView,
NestedScrollingChild2, NestedScrollingChild3 {
public abstract static class Adapter<VH extends ViewHolder> {
/**
* 通知任何被注册的观察者 , fromPosition 位置的 item 元素移动到了 toPosition 位置 ;
*
* 这是一个结构性的变化事件 ;
* 表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 ,
* 尽管它们的位置已经发生了变化 ;
* 也就是说 RecyclerView 只刷新涉及到的 fromPosition 和 toPosition 这 2 个元素 ,
* 其它元素不变 ;
*
* @param fromPosition 元素移动前的位置 ;
* @param toPosition 元素移动后的新位置 ;
*/
public final void notifyItemMoved(int fromPosition, int toPosition) {
mObservable.notifyItemMoved(fromPosition, toPosition);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
运行效果 : 动画效果是系统自带的 , 可以自己实现 ;
二、数据改变
批量修改数据 : 调用 RecyclerView.Adapter 的 void notifyDataSetChanged( ) 方法 , 通知数据发生了改变 ;
该方法的作用是通知任何被注册的观察者 , 数据集发生了改变 ;
调用该方法刷新数据 , 比调用其它方法更有效 , 但是没有动画效果 ;
数据改变事件类型 : 有两种不同的类型 , item 元素改变 和 结构性改变 ;
① item 元素改变 : 指的是单个的 item 的数据更新 , 但是位置没有改变 ;
② 结构性改变 : 指的是有新的数据被插入 , 删除 , 移动 , 位置发生了改变 ;
参数说明 :
int positionStart 参数 : 被修改的元素在原数据集中首个元素的位置索引 ;
int itemCount 参数 : 数据集中被修改元素个数 ;
注意 :
该方法不指定数据集发生了哪些变化 , 强制要求任何观察者对象去呈现所有存在的 item 条目和结构 , 这些数据可能已经失效 ;
布局管理器 LayoutManager 会强制所有数据重新绑定 , 并重新读取所有可视组件的布局 ;
如果适配器调用了本方法 , 通知数据发生了改变 , RecyclerView 会尝试去 为适配器 同步可见的结构性改变事件 ;
这样有助于动画和可视化对象的持续 , 但是单独的 item 元素组件需要重新被绑定 ;
代码示例 : 先移动数据 , 再删除三个数据 ;
// 先移除第 0 个
names.remove(0);
// 然后在第 7 个位置插入, 此时变为第 7 个元素
names.add(7, "宋江");
// 删除第 0 ~ 2 个元素
names.remove(0);
names.remove(0);
names.remove(0);
adapter.notifyDataSetChanged();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
RecyclerView.Adapter.notifyItemInserted(int position) 函数原型 : 该函数定义在 RecyclerView 的内部类 Adapter 中 ;
public class RecyclerView extends ViewGroup implements ScrollingView,
NestedScrollingChild2, NestedScrollingChild3 {
public abstract static class Adapter<VH extends ViewHolder> {
/**
* 通知任何被注册的观察者 , 数据集发生了改变 ;
*
* 数据改变事件 , 有两种不同的类型 , item 元素改变 和 结构性改变 ;
* item 元素改变时单个的 item 的数据更新 , 但是位置没有改变 ;
* 结构性改变指的是有新的数据被插入 , 删除 , 移动 , 位置发生了改变 ;
*
* 该事件不指定数据集发生了哪些变化 , 强制要求任何观察者对象去呈现所有存在的 item 条目和结构 , 这些数据可能已经失效 ;
* 布局管理器 LayoutManager 会强制所有数据重新绑定 , 并重新读取所有可视组件的布局 ;
*
* 如果适配器调用了本方法 , 通知数据发生了改变 , RecyclerView 会尝试去 为适配器 同步可见的结构性改变事件 ;
* 这样有助于动画和可视化对象的持续 , 但是单独的 item 元素组件需要重新被绑定 ;
*
* 如果你正在写一个适配器 , 使用该方法 , 比使用多个指定的变化方法 , 更加有效 ;
*
* @see #notifyItemChanged(int)
* @see #notifyItemInserted(int)
* @see #notifyItemRemoved(int)
* @see #notifyItemRangeChanged(int, int)
* @see #notifyItemRangeInserted(int, int)
* @see #notifyItemRangeRemoved(int, int)
*/
public final void notifyDataSetChanged() {
mObservable.notifyChanged();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
运行效果 : 该操作没有动画效果 , 只是刷新数据显示 ;
三、完整代码示例
完整代码示例 仅做参考 :
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);
}
});
// 数据改变
findViewById(R.id.data_change).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 先移除第 0 个
names.remove(0);
// 然后在第 7 个位置插入, 此时变为第 7 个元素
names.add(7, "宋江");
// 删除第 0 ~ 2 个元素
names.remove(0);
names.remove(0);
names.remove(0);
adapter.notifyDataSetChanged();
}
});
}
/**
* 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);
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
四、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 打开 )
文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。
原文链接:hanshuliang.blog.csdn.net/article/details/113546805
- 点赞
- 收藏
- 关注作者
评论(0)