RecyclerView的Adapter:
1.item的重用无需关心;
2.强制要求实现一个ViewHolder;
创建一个类(MyAdapter)继承于RecyclerView.Adapter;
定义一个ViewHolder;
搭建基础Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>
{
private Context mContext;
private List<String> dataList = new ArrayList<>();
public MyAdapter(Context context, List<String> data)
{
mContext = context;
dataList = data;
}
/**
* 当解析布局这样子写时:
* View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, parent, false);
* item中最外层布局的layout属性才起作用;eg:
*
* 当解析布局这样子写时:
* View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, null);
* item中最外层布局的layout属性则不起作用;
*
* viewType:多布局使用的;
*
* @param parent
* @param viewType
* @return
*/
@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, parent, false);
return new MyHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyHolder holder, int position)
{
holder.textView.setText(dataList.get(position));
}
@Override
public int getItemCount()
{
return dataList.size();
}
public class MyHolder extends RecyclerView.ViewHolder
{
private TextView textView;
/**
* 接收Item的布局对象
*
* @param itemView
*/
public MyHolder(@NonNull View itemView)
{
super(itemView);
textView = itemView.findViewById(R.id.textView);
}
}
}
使用RecyclerView:
private MyAdapter myAdapter;
private RecyclerView listRecyclerView;
private List<String> listData = new ArrayList<>();
listRecyclerView = findViewById(R.id.recycler_view);
//设置布局管理器;
listRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//new LinearLayoutManager;跟ListView一样的排列方式;
//LinearLayoutManager.HORIZONTAL:设置滑动的方向为横向;
//LinearLayoutManager.VERTICAL:设置滑动的方向为纵向;
//reverseLayout-->false:设置数据正序排列还是反序排列;eg:1...26为正序设置为false;26..1为反序设置为true;
listRecyclerView.setLayoutManager(
new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
//new GridLayoutManager:跟GridView一样的排列方式;
//3-->spanCount:如果方向为LinearLayoutManager.VERTICAL:则是设置有多少列;
// LinearLayoutManager.HORIZONTAL:则是设置有多少行;
//LinearLayoutManager.HORIZONTAL:设置方向;
//reverseLayout-->false:设置数据正序排列还是反序排列;eg:1...26为正序设置为false;26..1为反序设置为true;
listRecyclerView.setLayoutManager(
new GridLayoutManager(this, 3, LinearLayoutManager.HORIZONTAL, false));
//new StaggeredGridLayoutManager:瀑布流的排列方式;即当每个item需要显示的数据大小不一样时,则每个item的高度不会对齐;
//3-->spanCount:如果方向为LinearLayoutManager.VERTICAL:则是设置有多少列;
// LinearLayoutManager.HORIZONTAL:则是设置有多少行;
//LinearLayoutManager.HORIZONTAL:设置方向;
listRecyclerView.setLayoutManager(
new StaggeredGridLayoutManager(3, LinearLayout.HORIZONTAL));
myAdapter = new MyAdapter(this, listData);
listRecyclerView.setAdapter(myAdapter;
ps–>item布局的最外层布局必须使用wrap_content;如果使用match_parent则会一个Item占一页;
getAdapterPosition():获得适配器的下标;当前点击的Item的下标;
ps:瀑布流的排列形式;
ReyclerView的Item的点击事件:
1.在Adapter中创建:
第一种创建方式:
public class MyHolder extends RecyclerView.ViewHolder
{
private TextView textView;
/**
* 接收Item的布局对象
*
* @param itemView
*/
public MyHolder(@NonNull View itemView)
{
super(itemView);
textView = itemView.findViewById(R.id.textView);
itemView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (onItemClickListener != null)
{
onItemClickListener.onItemClick(v, getAdapterPosition());
}
}
});
}
}
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
this.onItemClickListener = onItemClickListener;
}
public interface OnItemClickListener
{
void onItemClick(View view, int position);
}
2.第二种创建方式:
@Override
public void onBindViewHolder(@NonNull MyHolder holder, int position)
{
holder.textView.setText(dataList.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (onItemClickListener != null)
{
onItemClickListener.onItemClick(v, position);
}
}
});
}
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
this.onItemClickListener = onItemClickListener;
}
public interface OnItemClickListener
{
void onItemClick(View view, int position);
}
在MainActivity中使用:
myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener()
{
@Override
public void onItemClick(View view, int position)
{
//添加数据单条数据时;
//position-->添加在position的位置;
//使用notifyItemInserted;则只会刷新添加的那条数据;
myAdapter.notifyItemInserted(position);
//添加多条数据;
//position-->从position的位置开始添加;
//itemCount:5-->一共需要添加几条;
myAdapter.notifyItemRangeInserted(position, 5);
//删除单条数据;
//position-->删除在position的位置的数据;
myAdapter.notifyItemRemoved(position);
//删除多条数据;
//position-->从position的位置开始删除;
//itemCount:5-->一共需要删除几条;
myAdapter.notifyItemRangeRemoved(position, 5);
//点击当前的position,使数据移到最顶端;
String str = listData.remove(position);
listData.add(str);
myAdapter.notifyItemMoved(position, 0);
//修改数据;
myAdapter.notifyItemChanged(position);
//批量修改
myAdapter.notifyItemRangeChanged(position, 6);
//滚动到第几个下标;
listRecyclerView.scrollToPosition(position);
}
});
设置显示的动画:
listRecyclerView.setItemAnimator(new DefaultItemAnimator());
设置每个item的分割线:
listRecyclerView.addItemDecoration(new MyItemDecoration(this));
自定义一个分割线的类:
public class MyItemDecoration extends RecyclerView.ItemDecoration
{
/**
* 系统的Drawable,用来话ListView的分割线的资源
*/
private int[] ATTR = {android.R.attr.listDivider};
/**
* 分割线的资源;
*/
private Drawable drawable;
public MyItemDecoration(Context context)
{
//获得Drawable资源的属性;
TypedArray typedArray = context.obtainStyledAttributes(ATTR);
//获取第一个Drawable;
drawable = typedArray.getDrawable(0);
//释放资源;
typedArray.recycle();
}
/**
* 分割线的绘制;
*
* @param c
* @param parent
* @param state
*/
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent,
@NonNull RecyclerView.State state)
{
super.onDraw(c, parent, state);
//parent.getChildCount()-->获取一共有多少个Item;
for (int i = 0; i < parent.getChildCount(); i++)
{
//最后一个不用绘制分割线;
if (i == parent.getChildCount() - 1)
{
return;
}
//获取第i个ItemView;
View itemView = parent.getChildAt(i);
//获取item的左边的坐标;
int left = itemView.getLeft();
//获取item的下边的坐标;
int top = itemView.getBottom();
//获取item的右边的坐标;
int right = itemView.getRight();
//获取分割线的下边的坐标;drawable.getIntrinsicHeight()-->分割线资源的高度;
int bottom = itemView.getBottom() + drawable.getIntrinsicHeight();
//设置分割线的坐标;
drawable.setBounds(left, top, right, bottom);
//绘制画布;
drawable.draw(c);
}
}
/**
* 设置每个Item需要预留出来的空间,供分割线使用;
*
* @param outRect
* @param view
* @param parent
* @param state
*/
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull RecyclerView.State state)
{
super.getItemOffsets(outRect, view, parent, state);
// drawable.getIntrinsicHeight():底部需要预留出来的空间;
outRect.set(0, 0, 0, drawable.getIntrinsicHeight());
}
}