RecyclerView控件的特点:
从整体上看,RecyclerView架构提供了一种插拔式的体验,它具有高度的解耦、异常的灵活性和更高的效率,通过设置它提供的不同LayoutManager、ItemDecoration、ItemAnimator可实现更加丰富的效果,但是RecyclerView也有缺点:设置列表的分割线时需要自定义,另外列表的点击事件需要自己实现。
添加依赖:
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
使用RecyclerView:
private RecyclerView recyclerView;
private List mList;
private HomeAdapter homeAdapter;
private LinearLayoutManager manager;
manager=new LinearLayoutManager(this);
//manager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(manager);//设置布局管理器用于设置条目的排列方式(默认垂值)
//添加分割线
recyclerView.addItemDecoration(new
DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL_LIST));
recyclerView.setItemAnimator(new DefaultItemAnimator());//设置item增加和删除时的动画
homeAdapter=new HomeAdapter(this,mList);//传出数据
recyclerView.setAdapter(homeAdapter);//添加adapter
View布局:
主布局activity_main.xml文件:
子布局item_recycler.xml文件:
Adapter适配器和分割线:
Adapter最大的改进就是对ViewHolder进行了封装定义,我们只需要自定义一个ViewHolder继承RecyclerView.ViewHolder就可以了,另外,Adapter继承了RecyclerView.Adapter,在onCreateViewHolder中加载条目布局,在onBindViewHolder中将视图与数据进行绑定。
1、类似于ListView式布局所对应的适配器HomeAdapter.java文件:
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 com.dpl.recyclerviewdemo.R;
import java.util.List;
/**
* 功能:数据适配器
*/
public class HomeAdapter extends RecyclerView.Adapter {
private Context context;
private List mList;
private OnItemClickListener onItemClickListener;
public HomeAdapter(Context context, List mList){//传入数据
this.context=context;
this.mList=mList;
}
public void removeData(int position){ //移除数据
mList.remove(position);
notifyItemRemoved(position);
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_recycler,viewGroup,false));
}
@Override
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int i) {
myViewHolder.textView.setText(mList.get(i));
if (onItemClickListener!=null){
myViewHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos=myViewHolder.getLayoutPosition();
onItemClickListener.onItemClick(myViewHolder.textView,pos);
}
});
myViewHolder.textView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos=myViewHolder.getLayoutPosition();
onItemClickListener.onItemLongClick(myViewHolder.textView,pos);
return false;
}
});
}
}
@Override
public int getItemCount() {
return mList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
MyViewHolder(@NonNull View itemView) {
super(itemView);
textView=itemView.findViewById(R.id.tv_item);
}
}
/**
* 自定义列表条目的点击事件
*/
public interface OnItemClickListener{
void onItemClick(View view,int position);
void onItemLongClick(View view,int position);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener=onItemClickListener;
}
}
设置类似于ListView的自定义分割线DividerItemDecoration.java文件:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* 功能:绘制类似ListView 的RecyclerView子布局item的分割线
*/
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS=new int[]{android.R.attr.listDivider};//android.R.attr.listDivider作为Item间的系统默认分割线,并且支持横向和纵向
public static final int HORIZONTAL_LIST= LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST=LinearLayoutManager.VERTICAL;
private Drawable mDivider;//Drawable就是一个可画的对象,其可能是一张位图(BitmapDrawable),也可能是一个图形(ShapeDrawable),象
private int mOrientation;
public DividerItemDecoration(Context context,int orientation){
final TypedArray a=context.obtainStyledAttributes(ATTRS);
//用TypedArray获取XML中的属性,通过Context的obtainStyledAttributes方法创建TypedArray,然后用getXXX来获取对应的属性。
mDivider=a.getDrawable(0);
a.recycle();//不要忘记回收
setOrientation(orientation);
}
public void setOrientation(int orientation){//设置排列方向
if (orientation!=HORIZONTAL_LIST&&orientation!=VERTICAL_LIST){
throw new IllegalArgumentException("invalid orientation");//非法数据异常处理
}
mOrientation=orientation;
}
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent) {//根据传进来的orientation进行绘制
if (mOrientation==VERTICAL_LIST){
drawVertical(c,parent);
}else {
drawHorizontal(c,parent);
}
}
public void drawVertical(Canvas c,RecyclerView parent){//绘制纵向分割线
final int left=parent.getPaddingLeft();//获取左边界距离
final int right=parent.getWidth()-parent.getPaddingRight();
final int childCount=parent.getChildCount();//获取子布局数量
for (int i=0;i
运行图:
2、实现GridView
适配器使用HomeAdapter.java文件。
自定义Item分割线DividerGridItemDecoration.java文件:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
/**
* 功能:GridViewItem分割线
*/
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS=new int[]{android.R.attr.listDivider};
private Drawable mDivider;
public DividerGridItemDecoration(Context context){
final TypedArray array=context.obtainStyledAttributes(ATTRS);
mDivider=array.getDrawable(0);
array.recycle();//回收
}
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
drawHorizontal(c,parent);
drawVertical(c,parent);
}
private int getSpanCount(RecyclerView parent){
//获取列数
int spanCount=-1;
RecyclerView.LayoutManager layoutManager=parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager){
spanCount=((GridLayoutManager)layoutManager).getSpanCount();
}else if (layoutManager instanceof StaggeredGridLayoutManager){
spanCount=((StaggeredGridLayoutManager)layoutManager).getSpanCount();
}
return spanCount;
}
public void drawHorizontal(Canvas c,RecyclerView parent){
int childCount=parent.getChildCount();
for (int i=0;i=childCount)//如果是最后一列,则不需要绘制右边
return true;
}
}
return false;
}
private boolean isLastRaw(RecyclerView parent,int position,int spanCount,int childCount){
RecyclerView.LayoutManager layoutManager=parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager){
childCount=childCount-childCount%spanCount;
if (position>=childCount)//如果是最后一行,则不需要绘制底部
return true;
}else if (layoutManager instanceof StaggeredGridLayoutManager){
int orientation=((StaggeredGridLayoutManager)layoutManager).getOrientation();
//StaggeredGridLayoutManager且纵向滚动
if (orientation==StaggeredGridLayoutManager.VERTICAL){
childCount=childCount-childCount%spanCount;
//如果是最后一行,则不需要绘制底部
if (position>=childCount)
return true;
}else{//StaggeredGridLayoutManager且横向滚动
//如果是最后一行,则不需要绘制底部
if ((position+1)%spanCount==0){
return true;
}
}
}
return false;
}
public void getItemOffsets(Rect outRect,int itemPosition,RecyclerView parent){
int spanCount=getSpanCount(parent);//获取列数
int childCount=parent.getAdapter().getItemCount();
if (isLastRaw(parent,itemPosition,spanCount,childCount)){//如果是最后一行,则不需要绘制底部
outRect.set(0,0,mDivider.getIntrinsicWidth(),0);
}else if (isLastColum(parent,itemPosition,spanCount,childCount)){
outRect.set(0,0,0,mDivider.getIntrinsicHeight());
}else {
outRect.set(0,0,mDivider.getIntrinsicWidth(),mDivider.getIntrinsicHeight());
}
}
}
运行图:
3、实现瀑布流StaggeredGridView.java文件:
Adapter适配器:StaggeredHomeAdapter.java文件
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 com.dpl.recyclerviewdemo.R;
import java.util.ArrayList;
import java.util.List;
/**
* 功能:瀑布流的适配器
*/
public class StaggeredHomeAdapter extends RecyclerView.Adapter {
private List mDatas;
private LayoutInflater mInflater;
private List mHeights;
private OnItemClickListener onItemClickListener;
public interface OnItemClickListener{
void onItemClick(View view,int position);
void onItemLongClick(View view,int position);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener=onItemClickListener;
}
public StaggeredHomeAdapter(Context context,List datas){
mInflater=LayoutInflater.from(context);
mDatas=datas;
mHeights=new ArrayList();
for (int i=0;i
瀑布流的分割线使用DividerGridItemDecoration.java文件。
运行图:
Control控制器:MainActivity.java文件
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.widget.Toast;
import com.dpl.recyclerviewdemo.adapter.HomeAdapter;
import com.dpl.recyclerviewdemo.adapter.StaggeredHomeAdapter;
import com.dpl.recyclerviewdemo.util.DividerGridItemDecoration;
import com.dpl.recyclerviewdemo.util.DividerItemDecoration;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List mList;
private HomeAdapter homeAdapter;
private LinearLayoutManager manager;
private StaggeredHomeAdapter staggeredHomeAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
}
private void initData(){//初始化数据
mList=new ArrayList<>();
for (int i=1;i<100;i++){
mList.add(i+"");
}
}
private void initView(){ //初始化view
recyclerView=this.findViewById(R.id.id_recyclerView);
//设置ListView
// setListView();
//设置GridView
// setGridView();
//设置瀑布流StaggeredGridView
setWaterfallView();
}
public void setListView(){
manager=new LinearLayoutManager(this);
//manager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(manager);
recyclerView.addItemDecoration(new DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL_LIST));
recyclerView.setItemAnimator(new DefaultItemAnimator());//设置item增加和删除时的动画
homeAdapter=new HomeAdapter(this,mList);//传出数据
setLister();
recyclerView.setAdapter(homeAdapter);//添加adapter
}
public void setGridView(){
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
recyclerView.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
recyclerView.setItemAnimator(new DefaultItemAnimator());//设置item增加和删除时的动画
homeAdapter=new HomeAdapter(this,mList);//传出数据
setLister();
recyclerView.setAdapter(homeAdapter);//添加adapter
}
public void setWaterfallView(){
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
recyclerView.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
staggeredHomeAdapter=new StaggeredHomeAdapter(this,mList);
staggeredHomeAdapter.setOnItemClickListener(new StaggeredHomeAdapter.OnItemClickListener(){
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this,"点击第"+(position+1)+"条",Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, final int position) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("确认删除吗?")
.setNegativeButton("取消",null)
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
staggeredHomeAdapter.removeData(position);
}
});
}
});
recyclerView.setAdapter(staggeredHomeAdapter);
}
public void setLister(){
homeAdapter.setOnItemClickListener(new HomeAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this,"点击第"+(position+1)+"条",Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, final int position) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("确认删除吗?")
.setNegativeButton("取消",null)
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
homeAdapter.removeData(position);
}
});
}
});
}
}
参考博客:
https://blog.csdn.net/crazyZhangxl/article/details/81043205
https://blog.csdn.net/dodod2012/article/details/79030559
https://blog.csdn.net/SuperBigLw/article/details/53404489