RecyclerView 是一个容器,它用于显示列表形式 (list) 或者网格形式 (grid) 的数据,比如文本或者照片。
当列表滑动的时候,实际上只有少量邻近的视图会显示在屏幕上。当视图滑出屏幕时,RecyclerView 会复用它并且填充新的数据。由于它是通过回收已有的结构而不是持续创建新的列表项,所以它可以有效提高应用的时间效率和空间效率。
RecyclerView
使用 ViewHolder
模式,可以提高性能,因为它无需频繁调用 findViewById()
方法即可访问表项的视图;LayoutManager
,支持纵向滑动的列表和横向滑动的列表,以及交错布局的列表和网格布局的列表。还可以创建自定义的 LayoutManager
;RecyclerView 兼顾了灵活性和个性化,它是功能强大的工具。
LayoutManager类是一个抽象类,安卓给我们提供了三个它的实现类供我们使用:
LinearLayoutManager给我们提供了一些API让我们可以对展示效果进行更丰富的操作。
我们可以在它的构造方法中传入它的列数。
宽度相同高度不同的ItemView。
确定RecyclerView的样式,是线性的,网格的还是瀑布流的
用来处理视图和数据之间的关系,一般情况下和ViewHolder搭配使用。
每个Adapter都必须继承自RecyclerView.Adapter
.并实现三个方法:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
}
onCreateViewHolder创建ViewHolder并返回
//onCreateViewHolder接受一个ViewGroup(通常是RecyclerView)和一个视图类型整数值作为参数,并返回一个新的ViewHolder实例,该实例持有新创建或复用的视图
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.itemlayout,parent,false));
}
onBindViewHold: 将数据放入ViewHolder中
//通过ViewHolder来绑定数据
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
//给ViewHolder持有的控件实例初始化
holder.mIv.setImageResource(getIcon(position));
holder.mTv.setText(dataSource.get(position));
//为瀑布流布局设置动态高度
if (recyclerView.getLayoutManager().getClass() == StaggeredGridLayoutManager.class)
{
//如果当前布局为瀑布流布局,则设置随机高度
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,getRandomHight());
holder.mTv.setLayoutParams(params);
}
else
{
//否则设置普通的宽高
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
holder.mTv.setLayoutParams(params);
}
if (addDataPosition == position)
{
holder.mItemView.setBackgroundColor(Color.RED);
}
//item点击事件
holder.mItemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//调用接口的回调方法
if (onItemClickListener!=null)
{
onItemClickListener.onItemClick(position);
}
}
});
}
getItermCount: 返回展示列表的数量
这个方法直接返回数据源(一般为一个List)的大小就行
容纳了ItemView的实例。可以在ViewHolder中创建ItemView中的控件实例,并通过ItemView的findViewById方法完成控件实例的初始化操作。
public class ViewHolder extends RecyclerView.ViewHolder {
//ViewHolder类通常用于保存每个列表项的视图以及与这些视图相关的数据
private final TextView mName;
private final TextView mPwd;
private final TextView mId;
//ViewHolder类的构造函数,它接收一个View对象作为参数。在构造函数中,通过给定的View对象找到并保存了对应的TextView
public ViewHolder(View view) {
super(view);
mName = view.findViewById(R.id.name);
mPwd = view.findViewById(R.id.pwd);
mId = view.findViewById(R.id.id);
}
}
//LinearLayoutManager 构造函数有一个上下文参数
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
//如果想要将数据横向排列
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//如果想到将数据倒序排列
linearLayoutManager.setReverseLayout(true);
//为recyclerView设置布局管理器
mRecyclerView.setLayoutManager(linearLayoutManager);
//GridLayoutManager 构造函数有两个参数,分别为上线文Context和网格布局的列数
GridLayoutManager gridLayoutManager = new GridLayoutManager(MainActivity.this ,2);
mRecyclerView.setLayoutManager(gridLayoutManager);
//StaggeredGridLayoutManager 构造函数有两个参数,分别为列数和布局方向
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(staggeredGridLayoutManager);
为了让瀑布流布局出现层次的感觉,需要在Adapter中进行一下设置
在onBindViewHolder方法中添加如下代码
if (recyclerView.getLayoutManager().getClass() == StaggeredGridLayoutManager.class)
{
//如果当前布局问瀑布流布局,则设置随机高度
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,getRandomHight());
holder.mTv.setLayoutParams(params);
}
//获取一个随机的值
private int getRandomHight()
{
return (int )(Math.random()*1000);
}
需要实现接口
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> implements View.OnClickListener {
}
声明接口
//自定义一个监听的接口,里面包含itemclick的监听方法,主要用于拿数据,方便外部调用拿数据
public interface onRecyclerViewItemClickListener{
void onItemClick(View view,int img);
}
public class ViewHolder extends RecyclerView.ViewHolder {
、、、、、
//定义一个设置Listener的方法(),作用是暴露给外面的调用者,方便调用
public void setOnItemClickListener(MyRecyclerViewAdapter.OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
//将点击事件转移给外面的调用者
@Override
public void onClick(View v) {
if (mOnRecyclerViewItemClickListener != null) {
//通过v.getTag()接受数据
mOnRecyclerViewItemClickListener.onItemClick(v, (Integer) v.getTag());
}
}
myRecyclerViewAdapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
Toast.makeText(MainActivity.this,"第"+position+"条数据被点击",Toast.LENGTH_SHORT).show();
}
});
//添加数据
public void addData(int position)
{
addDataPosition = position;
dataSource.add(position,"插入的数据");//dataSource是一个list数组
notifyItemInserted(position);//设置数据增加更新
notifyItemRangeChanged(position,dataSource.size()-position);//设置数据下标更新
}
//删除数据
public void deleteData(int position)
{
addDataPosition = -1;
dataSource.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,dataSource.size()-position);
}