您的位置:首页 > 移动开发 > Android开发

Android RecyclerView封装RecyclerAdapter及解决与ScrollView冲突

2017-09-21 12:45 597 查看

介绍

RecyclerView是support.v7包中的控件,可以说是ListView和GridView的增强升级版。

一、布局管理器

RecyclerView有三个默认布局管理器LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager。

例如,设置为一个3列的纵向网格布局:

GridLayoutManager mLayoutManager=new GridLayoutManager(GridActivity.this,3,GridLayoutManager.VERTICAL,false);
RecyclerView.setLayoutManager(mLayoutManager);

三个布局都支持横向和纵向排列以及反向滑动。
例如,想把RecyclerView改为横向滑动:

mLayoutManager.setOrientation(GridLayoutManager.HORIZONTAL);

二、封装BaseRecyclerAdapter

public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerViewHolder> {
protected Context mContext;
public List<T> list = new ArrayList<T>();
private OnItemClickListener onItemClickListener;
protected final static int TYPE_HEADER = 0;
protected final static int TYPE_BODY = 1;
private boolean hasHeader;

public boolean isHasHeader() {
return hasHeader;
}

public void setHasHeader(boolean hasHeader) {
this.hasHeader = hasHeader;
}

public BaseRecyclerViewAdapter(Context context, List<T> list) {
this.mContext = context;
if (list != null) {
this.list = list;
}
}

public void addData(List<T> data) {
list.addAll(data);
notifyDataSetChanged();
}

public void setData(List<T> data) {
list = data;
notifyDataSetChanged();
}

public void clear() {
if (list != null) {
list.clear();
notifyDataSetChanged();
}
}

public List<T> getData() {
return list;
}

@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RecyclerViewHolder(parent, createItem(viewType));
}

protected abstract ItemView<T> createItem(int viewType);

@Override
public void onBindViewHolder(RecyclerViewHolder holder, final int position) {
onClickListener(holder, position);
holder.bindView(getItem(position), position);
}

private void onClickListener(RecyclerViewHolder holder, final int position) {
if (onItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (hasHeader) {
if (position == 0) {
onItemClickListener.onItemClickListener(null, position);
} else {
onItemClickListener.onItemClickListener(list.get(position - 1), position);
}
} else {
onItemClickListener.onItemClickListener(list.get(position), position);
}

}
});
}
}

public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}

@Override
public int getItemCount() {
if (hasHeader) {
return list.size() + 1;
} else {
return list.size();
}
}

@Override
public int getItemViewType(int position) {
if (hasHeader && position == 0) {
return TYPE_HEADER;
} else {
return TYPE_BODY;
}
}

/**
* 获取item
*
* @param position
* @return
*/
public T getItem(int position) {
if (position < list.size() && !hasHeader) {
return list.get(position);
} else if (position < list.size() + 1 && hasHeader && position - 1 >= 0) {
return list.get(position - 1);
}
return null;
}

public interface OnItemClickListener<T> {
void onItemClickListener(T t, int position);
}
}

public abstract class ItemView<T> {
protected Context mContext;

protected View getView(ViewGroup parent) {
View v = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(), parent, false);
ButterKnife.bind(this, v);
mContext = parent.getContext();
return v;
}

public abstract void bindView(T t, int position);

protected abstract int getLayoutId();

}

public class RecyclerViewHolder<T> extends RecyclerView.ViewHolder {
private ItemView<T> item;

public RecyclerViewHolder(ViewGroup parent, ItemView<T> itemView) {
super(itemView.getView(parent));
this.item = itemView;
}

public void bindView(T t, int position) {
item.bindView(t, position);
}
}


三、与Scrollview冲突解决

横向GridLayout:

public class FullyGridLayoutManager extends GridLayoutManager {

public FullyGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}

public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}

private int[] mMeasuredDimension = new int[2];

@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);

int width = 0;
int height = 0;
int count = getItemCount();
int span = getSpanCount();
for (int i = 0; i < count; i++) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);

if (getOrientation() == HORIZONTAL) {
if (i % span == 0) {
width = width + mMeasuredDimension[0];
}
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
if (i % span == 0) {
height = height + mMeasuredDimension[1];
}
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}

switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}

switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}

setMeasuredDimension(width, height);
}

private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
if (position < getItemCount()) {
try {
View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

竖向Linearlayout:

public class FullyLinearLayoutManager extends LinearLayoutManager {

private static final String TAG = FullyLinearLayoutManager.class.getSimpleName();

public FullyLinearLayoutManager(Context context) {
super(context);
}

public FullyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}

private int[] mMeasuredDimension = new int[2];

@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
int widthSpec, int heightSpec) {

final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);

Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode
+ " \nheightMode " + heightSpec
+ " \nwidthSize " + widthSize
+ " \nheightSize " + heightSize
+ " \ngetItemCount() " + getItemCount());

int width = 0;
int height = 0;
for (int i = 0; i < getItemCount(); i++) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);

if (getOrientation() == HORIZONTAL) {
width = width + mMeasuredDimension[0];
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
height = height + mMeasuredDimension[1];
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}

switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}

setMeasuredDimension(width, height);
}

private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
try {
View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException

if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();

int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);

int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);

view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: