版权声明:本文为博主原创文章,码字不易,转载时请标明具体出处(博主名+博客页面链接),万分感谢Thanks♪(・ω・)ノ https://blog.csdn.net/An_nAl/article/details/81063764
添加依赖
compile 'com.android.support:recyclerview-v7:26.+'
Recyclerview.getLayoutPosition()问题
使用Recyclerview 时,如果要添加item的点击监听等功能,可以在Recyclerview.Adapter的onBindViewHolder中设置:
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.tv.setHeight(150*(1+position%4));
holder.tv.setWidth(150*(1+position%4));
holder.tv.setText(data.get(position));
if(mOnItemClickListener!=null){
holder.tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos=holder.getLayoutPosition();
mOnItemClickListener.onItemClick(v,pos);
}
});
holder.tv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos=holder.getLayoutPosition();
mOnItemClickListener.onItemLongClick(v,pos);
return false;
}
});
}
}
注意这里使用了ViewHolder的getLayoutPosition方法,此方法返回的pos值与onBindViewHolder方法传入的position值有可能不同。
根据SDK中的解释,在Recyclerview 进行添加、移除item等操作时,position位置可能会变化,而所有的adapter的刷新并不总是及时的,只有这个方法返回的才是当前item经过一些变换后所处的真正位置。
getLayoutPosition:返回布局中最新的计算位置,和用户所见到的位置一致,当做用户输入(例如点击事件)的时候考虑使用
getAdapterPosition:返回数据在Adapter中的位置(也许位置的变化还未来得及刷新到布局中),当使用Adapter的时候(例如调用Adapter的notify相关方法时)考虑使用
网格布局
xml布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:scrollbars="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
item布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:background="#d4d2d2"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_item"
android:layout_width="match_parent"
android:background="#FFFFFF"
android:layout_height="200dp"
android:layout_margin="10dp"
android:gravity="center"
android:textSize="22sp"
android:text="item"/>
</LinearLayout>
Adapter
public class InfoRecyclerViewAdapter extends RecyclerView.Adapter<InfoRecyclerViewAdapter.ViewHolder> {
private ArrayList<String> mData;
/**
* 事件回调监听
*/
private InfoRecyclerViewAdapter.OnItemClickListener onItemClickListener;
public InfoRecyclerViewAdapter(ArrayList<String> data) {
this.mData = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
// 实例化展示的view
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_vertical, parent, false);
// 实例化viewholder
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// 绑定数据
holder.tvItem.setText(mData.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
if(onItemClickListener != null) {
int pos = holder.getLayoutPosition();
onItemClickListener.onItemClick(holder.itemView, pos);
}
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if(onItemClickListener != null) {
int pos = holder.getLayoutPosition();
onItemClickListener.onItemLongClick(holder.itemView, pos);
}
//表示此事件已经消费,不会触发单击事件
return true;
}
});
}
@Override
public int getItemCount() {
return mData == null ? 0 : mData.size();
}
/**
* 新增item
*/
public void addNewItem() {
if(mData == null) {
mData = new ArrayList<>();
}
mData.add(0, "new Item");
notifyItemInserted(0);
}
/**
* 删除item
*/
public void deleteItem() {
if(mData == null || mData.isEmpty()) {
return;
}
mData.remove(0);
notifyItemRemoved(0);
}
/**
* 更新整个列表数据
* @param data
*/
public void updateData(ArrayList<String> data) {
this.mData = data;
notifyDataSetChanged();
}
/**
* 设置回调监听
* @param listener
*/
public void setOnItemClickListener(InfoRecyclerViewAdapter.OnItemClickListener listener) {
this.onItemClickListener = listener;
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.tv_item)
TextView tvItem;
ViewHolder(View view) {
super( view);
ButterKnife.bind(this, view);
}
}
}
ItemDecoration样式drawable
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:centerColor="#ff00ff00"
android:endColor="#ff0000ff"
android:startColor="#ffff0000"
android:type="linear" />
<size android:height="4dp"/>
</shape>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name= "android:listDivider">@drawable/bg_divider </item >
</style>
ItemDecoration
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 a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, State state) {
drawHorizontal(c, parent);
drawVertical(c, parent);
}
/**
* 绘制水平分割线
*/
public void drawHorizontal(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();//item总个数
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.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin
+ mDivider.getIntrinsicWidth();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
/**
* 绘制垂直分割线
*/
public void drawVertical(Canvas c, RecyclerView parent) {
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.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin;
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
/**
* 列数
*/
private int getSpanCount(RecyclerView parent) {
int spanCount = -1;
LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
}
return spanCount;
}
/**
* 是否是最后一列
*/
private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
int childCount) {
LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
if ((pos + 1) % spanCount == 0) // 如果是最后一列,则不需要绘制右边
{
return true;
}
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
if ((pos + 1) % spanCount == 0) // 如果是最后一列,则不需要绘制右边
{
return true;
}
} else {
childCount = childCount - childCount % spanCount;
if (pos >= childCount) // 如果是最后一列,则不需要绘制右边
return true;
}
}
return false;
}
/**
* 是否是最后一行
* @param parent
* @param pos 当前item的位序
* @param spanCount 列数
* @param childCount item总个数
* @return
*/
private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
int childCount) {
LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
childCount = childCount - childCount % spanCount;
// 如果是最后一行,则不需要绘制底部
if (pos >= childCount){
return true;
}
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
// StaggeredGridLayoutManager 且纵向滚动
if (orientation == StaggeredGridLayoutManager.VERTICAL) {
childCount = childCount - childCount % spanCount;
// 如果是最后一行,则不需要绘制底部
if (pos >= childCount){
return true;
}
} else {
// StaggeredGridLayoutManager 且横向滚动
// 如果是最后一行,则不需要绘制底部
if ((pos + 1) % spanCount == 0) {
return true;
}
}
}
return false;
}
@Override
public void getItemOffsets(Rect outRect, int itemPosition,
RecyclerView parent) {
int spanCount = getSpanCount(parent);//列数
int childCount = parent.getAdapter().getItemCount();//item总个数
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());
}
}
}
activity
//竖直滑动,每行只显示四个
GridLayoutManager infoLayoutManager = new GridLayoutManager( this,4);
InfoRecyclerViewAdapter infoRecyclerViewAdapter = new InfoRecyclerViewAdapter(getData(), "");
// 设置布局管理器
infoRecyclerView.setLayoutManager(infoLayoutManager);
// 设置adapter
infoRecyclerView.setAdapter(infoRecyclerViewAdapter);
//设置间隔样式
infoRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
垂直列表(像ListView)
activity
infoLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
// 设置布局管理器
infoRecyclerView.setLayoutManager(infoLayoutManager);
// 设置adapter
infoRecyclerViewAdapter = new InfoRecyclerViewAdapter(getData());
//item的点击事件
infoRecyclerViewAdapter.setOnItemClickListener(new InfoRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(ActVerticalRecycler.this,"click " + position + " item", Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, int position) {
Toast.makeText(ActVerticalRecycler.this,"long click " + position + " item", Toast.LENGTH_SHORT).show();
}
});
infoRecyclerView.setAdapter(infoRecyclerViewAdapter);
//设置间隔样式
// infoRecyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL));
infoRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
// 设置Item添加和移除的动画
infoRecyclerView.setItemAnimator(new DefaultItemAnimator());
水平列表
activity
// 设置布局管理器
infoLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
infoRecyclerView.setLayoutManager(infoLayoutManager);
// 设置adapter
infoRecyclerViewAdapter = new InfoRecyclerViewAdapter( getData());
infoRecyclerView.setAdapter(infoRecyclerViewAdapter);
//设置间隔样式
// infoRecyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.HORIZONTAL));
infoRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
新增item
infoRecyclerViewAdapter.addNewItem();
// 由于Adapter内部是直接在首个Item位置做增加操作,增加完毕后列表移动到首个Item位置
infoLayoutManager.scrollToPosition(0);
删除item
infoRecyclerViewAdapter.deleteItem();
// 由于Adapter内部是直接在首个Item位置做删除操作,删除完毕后列表移动到首个Item位置
infoLayoutManager.scrollToPosition(0);