上一篇文章简单说了一下RecyclerView的基本用法,本篇文章打算说一下RecyclerView的详细用法,主要包含RecyclerView添加分割线及点击事件功能。其实主要也是打算看一下RecyclerView的源码,先把基本用法记录下来。这文章也是以前写的,现在只是搬过来一下,方便自己以后需要用到的时候查看,也方便自己更好的研究RecyclerView的源码,毕竟最基础的用法都不懂,谈什么看源码。
一、RecyclerView item点击事件实现
package recyclerview.xiaochao.com.recyclerviewdemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* @author xiaochao
* @description RecyclerView适配器
* @time 2017/12/23 10:46
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
//1.我们首先在MyAdapter中编写一个内部类MyViewHolder继承自RecyclerView.ViewHolder
class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tv;
public MyViewHolder(View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv);//此id为item布局中TextView的id
}
}
//2.让MyAdapter继承RecyclerView.Adapter<MyAdapter.MyViewHolder>,注意<>中是我们自定义的ViewHolder
private List<String> mList;
private Context mContext;
//3.通过构造函数传入数据与Context
public MyAdapter(Context context, List<String> stringList) {
mContext = context;
mList = stringList;
}
/**
* 加载条目布局
*
* @param parent
* @param viewType 可以根据这个值加载不同的布局
* @return RecyclerView中的每一个itemView
*/
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_recyclerview, parent, false);
MyViewHolder viewHolder = new MyViewHolder(itemView);
return viewHolder;
}
/**
* 将视图与数据进行绑定
*
* @param holder 可以将其看成itemView,onCreateViewHolder方法中返回的就是MyViewHolder
* @param position
*/
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.tv.setText(mList.get(position));
if(mOnItemClickListener!=null){//当mOnItemClickListener不为null时,
//说明RecyclerView已经调用了setOnItemClickListener(OnItemClickListener onItemClickListener)方法
holder.tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int pos = holder.getLayoutPosition();//获取点击的索引
mOnItemClickListener.onItemClick(holder.tv,pos);//执行onItemClick方法,具体实现在外部调用的时候实现
}
});
holder.tv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
int pos = holder.getLayoutPosition();//获取点击的索引
mOnItemClickListener.onItemLongClick(holder.tv,pos);
return false;
}
});
}
}
/**
* @return 要显示多少个item
*/
@Override
public int getItemCount() {
return mList.size();
}
/**
* 定义接口,可以到外部类去定义
*/
public interface OnItemClickListener{
void onItemClick(View view,int position);//item点击事件
void onItemLongClick(View view,int position);//item长按事件
}
//在适配器中申明我们定义的接口,让它为null
public OnItemClickListener mOnItemClickListener=null;
/**
* 为了给外部也就是我们new出来的该对象调用,将OnItemClickListener传入进来赋值给我们申明的接口mOnItemClickListener
* 具体实现方法包括item点击与长按的实现都在外部调用的时候实现
* @param onItemClickListener
*/
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.mOnItemClickListener = onItemClickListener;
}
}
然后我们在Activity中调用,处理点击事件回调
mMyAdapter = new MyAdapter(MainActivity.this, mList);
mMyAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this,"点击了"+position,Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, final int position) {
Toast.makeText(MainActivity.this,"长按了"+position,Toast.LENGTH_SHORT).show();
}
});
二、RecyclerView长按删除item实现
有时候我们需要能够将item移除,这个其实很好实现,只要在Adapter中增加几行代码即可。如上,我们已经实现了item的点击与长按事件,我们将删除item的功能放在长按事件里去实现,代码如下:首先在Adapter中增加删除item的方法,用来删除点击的item,代码如下:
public void removeData(int position){
mList.remove(position);
notifyItemRemoved(position);
}
接下来就是在Adapter调用setOnItemClickListener实现onItemLongClick方法时调用removeData方法:
mMyAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this,"点击了"+position,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 dialogInterface, int i) {
mMyAdapter.removeData(position);//这里执行删除item方法
}
}).show();
}
});
三、给item之间添加分割线
前面说了,RecyclerView中的item默认是没有分割线的,而ListView默认是有分割线的,那么我们如果需要加上分割线,该如何加呢?这里也不用太担心,RecyclerView提供了让我们自定义分割线的方法,首先我们需要自己定义一个类去继承RecyclerView.ItemDecoration,然后我们就可以自己开始实现去绘制我们想要的分割线了
public class DividerItemDecoration extends RecyclerView.ItemDecoration{
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
};
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mDivider;
private int mOrientation;
public DividerItemDecoration(Context context,int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
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(Canvas c, RecyclerView parent, RecyclerView.State state) {
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 < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom()+params.bottomMargin;
final int bottom = top+mDivider.getIntrinsicHeight();
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
}
public void drawHorizontal(Canvas c,RecyclerView parent){
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight()-parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight()+params.rightMargin;
final int right = left+mDivider.getIntrinsicHeight();
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if(mOrientation==VERTICAL_LIST){
outRect.set(0,0,0,mDivider.getIntrinsicHeight());
}else{
outRect.set(0,0,mDivider.getIntrinsicWidth(),0);
}
}
}
上面代码就是自己定义的一个简单的分割线类,上面我们只是把它定义出来,使用的话只需要一行代码就可以搞定,执行完下面步骤后,我们的RecyclerView中的item之间就有分割线了
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
版权声明:本文为xiaochao_develop原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。