RecyclerView的用处
- RecyclerView是support.v7包中的控件,可以说是ListView和GridView的增强升级版。
RecyclerView的优点
- 为什么要使用recycle view
简单使用recycle view
添加依赖库
implementation 'com.android.support:recyclerview-v7:27.1.1'
在布局文件中添加组件
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
编写每个item的布局
- 就是写recycle view每个单元的布局详情
- 一个recycle view可以加载多中布局文件,根据位置和类型加载不同的布局 后面详细总结
在activity或者Fragment中获取recycle view对象并且进行设置
- 代码如下
RecycleView recyclerView = findViewById(R.id.recycler_view);
//设置LayoutManager为LinearLayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//设置Adapter
recyclerView.setAdapter(new GeneralAdapter(this,datas));
- RecyclerView中默认带有三个布局管理器:LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager,这三种布局管理器都支持横向和纵向排列以及反向滑动。
编写adapter
public class GeneralAdapter extends RecyclerView.Adapter<GeneralAdapter.MyViewHolder> {
//当前上下文对象
Context context;
//RecyclerView填充Item数据的List对象
List<String> datas;
//构造函数 自己定义看需要传递什么参数 这里传递的是上下文的对象和数据
public GeneralAdapter(Context context,List<String> datas){
this.context = context;
this.datas = datas;
}
//创建ViewHolder
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//引入item布局并且实例化为对象
View v = View.inflate(context, R.layout.item_recycler,null);
//返回MyViewHolder的对象 这是自己创建的继承RecyclerView.ViewHolder的 类
return new MyViewHolder(v);
}
//绑定数据
// 通过调用布局里面的view对象进行数据方面的绑定
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.textView.setText(datas.get(position));
}
//告诉系统item的数量
@Override
public int getItemCount() {
return datas.size();
}
//继承RecyclerView.ViewHolder抽象类的自定义ViewHolder
class MyViewHolder extends RecyclerView.ViewHolder{
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
//通过每个itemView引入自己布局中的每个子View
textView = itemView.findViewById(R.id.text);
}
}
}
- RecyclerView的adapter需要继承RecyclerView.Adapter这个抽象类。后面是一个必须继承自RecyclerView.ViewHolder抽象类的ViewHolder的泛型约束,也就是GeneralAdapter.MyViewHolder这个内部类
- 在RecyclerView.Adapter抽象类有三个必须实现的抽象方法:
public abstract VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType);
public abstract void onBindViewHolder(@NonNull VH holder, int position);
public abstract int getItemCount();
以上就是RecycleView的简单使用
下面来说RecycleView的具体需求中需要掌握的地方
布局管理器
- RecyclerView自身带有三种默认的布局管理器:LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager。
-LinearLayoutManager将项目排列在一维列表中。使用RecyclerView LinearLayoutManager提供了像旧版本的功能ListView。 GridLayoutManager将项目排列在二维网格中,如棋盘上的方格。使用RecyclerView with GridLayoutManager 提供了像旧版本的功能GridView StaggeredGridLayoutManager 将项目排列在一个二维网格中,每列与之前的一列略有偏移,就像美国国旗中的星星一样。
LinearLayoutManager
- LinearLayoutManager线性布局管理器。布局管理器默认使用垂直排列布局,而需要水平排列布局的话则可以通过LinearLayoutManager对象的setOrientation方法设置。,此方法接收int类型的值,分别为RecyclerView中的两个Int常量:
LinearLayout.HORIZONTAL 和 LinearLayout.VERTICAL;
- 设置布局方向的时候 也可以通过构造函数进行 。第三个参数一般传false,它的用途是当为true时数据和滑动都是反向的。(TODO这个地方需要体验下真实效果)
public LinearLayoutManager(Context context, @RecyclerView.Orientation int orientation,
boolean reverseLayout)
GridLayoutManager
- 网格布局管理器顾名思义 item根据网格方式进行排列。跟线性布局管理器一样,也支持通过setOrientation()或者构造方法来设置Item的排列方向。
- 设置网格的行(对应着水平布局)或者列(对应着垂直布局)
recyclerView.setLayoutManager(new GridLayoutManager(this,3));
第二个参数就是行或者列的数目
StaggeredGridLayoutManager
- 瀑布流布局管理器 可以实现酷炫的瀑布流效果。它最常用的构造函数就一个StaggeredGridLayoutManager(int spanCount, int orientation),spanCount代表每行或每列的Item个数,orientation代表列表的方向,竖直或者水平。
- 需要注意的地方 要实现瀑布流效果(仅讨论竖直方向的瀑布流样式),每一个Item的高度要有所差别,如果所有的item的高度相同,就和网格样式是一样的展示效果。因此实现瀑布流效果开发者需要根据位置加载不同的item布局界面。这样就可以实现了。参考下面的总结。
item点击事件
有两种处理方式分别是
- 在Adapter里面直接对控件做点击事件
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
holder.textView.setText(datas.get(position));
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//do something
}
});
}
- 写接口,在Activity或Fragment上实现接口中定义的方法
- 定义回调接口
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
public interface OnItemLongClickListener {
boolean onItemLongClick(View view, int position);
}
- adapter 中进行设置
public class GeneralAdapter extends RecyclerView.Adapter<GeneralAdapter.MyViewHolder> {
//当前上下文对象
Context context;
//RecyclerView填充Item数据的List对象
List<String> datas;
public GeneralAdapter(Context context,List<String> datas){
this.context = context;
this.datas = datas;
}
private OnItemClickListener onItemClickListener;
private OnItemLongClickListener onItemLongClickListener;
public void setOnItemClickListener(OnItemClickListener listener) {
this.onItemClickListener = listener;
}
public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
this.onItemLongClickListener = onItemLongClickListener;
}
//绑定数据
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
holder.textView.setText(datas.get(position));
//通过接口回调响应点击事件
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(onItemClickListener != null){
onItemClickListener.onItemClick(view,position);
}
}
});
//通过接口回调响应长按事件
holder.textView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if(onItemLongClickListener != null){
return onItemLongClickListener.onItemLongClick(view,position);
}
return false;
}
});
}
- 在activity中的代码
//点击事件
adapter.setOnItemClickListener(new GeneralAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(GeneralActivity.this,datas.get(position)+"被点击了",
Toast.LENGTH_SHORT).show();
}
});
//长按事件
adapter.setOnItemLongClickListener(new GeneralAdapter.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(View view, int position) {
Toast.makeText(GeneralActivity.this,datas.get(position)+"被长按了",
Toast.LENGTH_SHORT).show();
return true;
}
});
根据Recycleview的位置加载不同的布局
@Override
public int getItemViewType(int position) {
if(position %2 == 0){
return 0;
}else{
return 2;
}
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v;
if(viewType == 0){
v = View.inflate(context,R.layout.item_recycler,null);
}else{
v = View.inflate(context,R.layout.item2_recycler,null);
}
return new MyViewHolder(v);
}
- getItemViewType() 这个方法顾名思义是用来设置每个item的类型的,传进来的参数是int类型的位置参数。返回类型同样是int类型。这个返回值是自定义的,自己知道什么样的数字代表什么样的类型就可以了。
- onCreateViewHolder()方法中传进来的参数就有viewType这个参数,然后根据这个参数进行不同的布局加载。
点击item在被点击的item上面显示一个对话框一样的东西
- 解决方案参考我的另外一篇文章链接
还有很多要掌握的技巧没有总结出来 以后会一一补充的。先列举如下
- 滑动动画
- 添加头和尾巴
- 上拉加载和下拉刷新
- item间隔线,
- 删除某个item,删除动画
网友评论