RecyclerView进阶

、RecyclerView之实现瀑布流排版
RecyclerView本身提供了三个LayoutManager的实现
LinearLayoutManager
GridLayoutManager
StaggeredGridLayoutManager
第一个和第二个大家比较常用,分别可以实现水平上下滑动的ListView效果和GridView的表格效果,今天我们就来
使用第三个比较陌生的StaggeredGridLayoutManager,让你实现瀑布流布局。
效果图如下:
瀑布流布局实现和LinearLayoutManager、GridLayoutManager没有太多的差别唯一差别是layoutManager和添加间
隔;
//使用StaggeredGridLayoutManager
StaggeredGridLayoutManager layoutManager = newStaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
rc_test.setLayoutManager(layoutManager);
rc_test.setAdapter(newMyAdapter());
//添加间隔
rc_test.addItemDecoration(newSpacesItemDecoration(16));
间隔线SpacesItemDecoration代码如下:
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpacesItemDecoration(int space) {
this.space = space;
@
Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.left space;
outRect.right space;
outRect.bottomspace;
if (parent.getChildAdapterPosition(view) == 0) {
outRect.top space;
}
}

、RecyclerView添加Header 使用了RecyclerView会发现RecyclerView并不能像ListView那样直接通过addHeaderView的方式添加头部,所以我 们要学习如何为RecycleView添加Header
在为RecyclerView添加Header的时候我们有如下问题需要思考:
如何为RecyclerView添加Header
如何让Header适配各种LayoutManager
对Adapter进行封装,使用更方便
1、如何为RecyclerView添加Header
RecycleView添加Header是通过控制Adapter的itemType来设置的,思路就是根据不同的itemType去加载不同的布
局。
adapter代码如下:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
public static final int TYPE_HEADER 0;//type0表示为headerView
public static final int TYPE_NORMAL 1;//type1表示为正常的item
private Context context;
private View headerView;//头部s
public MyAdapter(Context context) {
this.context = context;
publi
c void setHeaderView(View view) {
headerView= view;
//adapter0个位置添加一个View并刷新适配器
notifyItemInserted(0);
// notifyItemChanged(1);//
// notifyItemRangeChanged(1,10);//
// notifyItemRemoved(2);//
// notifyItemMoved(2,5);//
@
Override
public int getItemViewType(int position) {
if (headerView== null)
return TYPE_NORMAL;
if (position == 0)
return TYPE_HEADER;
return TYPE_NORMAL;
@
Override
public MyHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {if (headerView!= null && viewType == TYPE_HEADER)return newMyHolder(headerView);View view = View.inflate(viewGroup.getContext(), R.layout.item_staggered, null);return newMyHolder(view);} @Overridepublic void onBindViewHolder(MyHolder holder, final int position) {if (getItemViewType(position) == TYPE_HEADER)return;//正常item处理逻辑} @Overridepublic int getItemCount() {return 20;} public static class MyHolder extends RecyclerView.ViewHolder {public MyHolder(View itemView) {super(itemView);}}} Activity中调用如下:LinearLayoutManager layoutManager = newLinearLayoutManager(this);layoutManager.setOrientation(LinearLayoutManager.VERTICAL);rc_test.setLayoutManager(layoutManager);adapter = newMyAdapter(this);rc_test.setAdapter(adapter);View headerView = View.inflate(this,R.layout.header,null);adapter.setHeaderView(headerView);2、让Header适配各种LayoutManager上面写到为RecycleView添加Header是使用的LinearLayoutManager布局管理器,如果换成GridLayoutManager 或者StaggeredGridLayoutManager发现并不成功,所以GridLayoutManager和StaggeredGridLayoutManager要进 行单独的处理;为GridLayoutManager添加Header还需要添加如下代码:layoutManager.setSpanSizeLookup(newGridLayoutManager.SpanSizeLookup() {@Overridepublic int getSpanSize(int position) {int SpanCount = layoutManager.getSpanCount();//一个view所占单元格的个数, 默认是一个view占一个单元格return adapter.getItemViewType(position) == 0? SpanCount : 1;}});为了方便使用可以把上面放入adapter中使用,需要重写onAttachedToRecyclerView方法,代码如下:@Overridepublic void onAttachedToRecyclerView(RecyclerView recyclerView) {super.onAttachedToRecyclerView(recyclerView);RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();if(manager instanceof GridLayoutManager) {final GridLayoutManager gridManager = ((GridLayoutManager) manager);gridManager.setSpanSizeLookup(newGridLayoutManager.SpanSizeLookup() {@Overridepublic int getSpanSize(int position) {int SpanCount = gridManager.getSpanCount();//一个view所占单元格的个数, 默认是一个view占一个单元格return getItemViewType(position) == 0? SpanCount : 1;}});}} 为StaggeredGridLayoutManager添加Header需要在Adapter中重写onViewAttachedToWindow方法:@Overridepublic void onViewAttachedToWindow(MyHolder holder) {super.onViewAttachedToWindow(holder);ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();if (lp != null&& lp instanceof StaggeredGridLayoutManager.LayoutParams&& holder.getLayoutPosition() == 0) {StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;p.setFullSpan(true);}} 3、将Adapter进行封装看到以上对RecyclewView添加Header的代码发现很多,我们不可能每一个有Header的Adapter都写这么多的代码逻辑,所以需要把上述代码逻辑进行封装到一个BaseRecycleViewAdapter中,代码如下:public abstract class BaseRecycleViewAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {public static final int TYPE_HEADER = 0;//type为0表示为headerViewpublic static final int TYPE_NORMAL = 1;//type为1表示为正常的itemprivate ArrayList<T> mDatas = newArrayList<>();private View mHeaderView;private OnItemClickListener itemClickListener;public void setOnItemClickListener(OnItemClickListener itemClickListener) {this.itemClickListener = itemClickListener;} public void setHeaderView(View headerView) {mHeaderView= headerView;notifyItemInserted(0);} public View getHeaderView() {return mHeaderView;} public void addDatas(ArrayList<T> datas) {mDatas.addAll(datas);notifyDataSetChanged();} @Overridepublic int getItemViewType(int position) {if (mHeaderView== null) return TYPE_NORMAL;if (position == 0) return TYPE_HEADER;return TYPE_NORMAL;} @Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {if (mHeaderView!= null && viewType == TYPE_HEADER) return newHolder(mHeaderView);return onCreate(parent, viewType);} @Overridepublic void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {if (getItemViewType(position) == TYPE_HEADER) return;final int pos = getRealPosition(viewHolder);final T data = mDatas.get(pos);onBind(viewHolder, pos, data);if (itemClickListener != null) {viewHolder.itemView.setOnClickListener(newView.OnClickListener() {@Overridepublic void onClick(View v) {itemClickListener.onItemClick(pos, data);}});}} @Overridepublic void onAttachedToRecyclerView(RecyclerView recyclerView) {super.onAttachedToRecyclerView(recyclerView);RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();if (manager instanceof GridLayoutManager) {final GridLayoutManager gridManager = ((GridLayoutManager) manager);gridManager.setSpanSizeLookup(newGridLayoutManager.SpanSizeLookup() {@Overridepublic int getSpanSize(int position) {return getItemViewType(position) == TYPE_HEADER? gridManager.getSpanCount() : 1;}});}} @Overridepublic void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {super.onViewAttachedToWindow(holder);ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();if (lp != null&& lp instanceof StaggeredGridLayoutManager.LayoutParams&& holder.getLayoutPosition() == 0) {StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;p.setFullSpan(true);}} /*** 获取item正确的position* @param holder* @return*/public int getRealPosition(RecyclerView.ViewHolder holder) {int position = holder.getLayoutPosition();return mHeaderView== null ? position : position - 1;} @Overridepublic int getItemCount() {return mHeaderView== null ? mDatas.size() : mDatas.size() + 1;} public abstract RecyclerView.ViewHolder onCreate(ViewGroup parent, final int viewType);public abstract void onBind(RecyclerView.ViewHolder viewHolder, int RealPosition, T data);public class Holder extends RecyclerView.ViewHolder {public Holder(View itemView) {super(itemView);}} /*** 处理item点击监听* @param <T>*/public interface OnItemClickListener<T> {void onItemClick(int position, T data);}} 具体集成BaseRecycleViewAdapter使用如下:public class MyAdapter2 extends BaseRecycleViewAdapter {@Overridepublic RecyclerView.ViewHolder onCreate(ViewGroup parent, int viewType) {View view = View.inflate(parent.getContext(), R.layout.item_staggered, null);return newMyHolder(view);} @Overridepublic void onBind(RecyclerView.ViewHolder viewHolder, int RealPosition, Object data) {} class MyHolder extends BaseRecycleViewAdapter.Holder {TextView text;public MyHolder(View itemView) {super(itemView);text = (TextView) itemView.findViewById(R.id.text);}}}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值