RecyclerViewLayoutManager分析 添加头部尾部

优化版本点击这里

RecyclerView使用也有一段时间了 他的出现是对ListView,GridView的进化,

LayoutManager负责布局Adpater负责数据处理自带缓存机制,不用开发者过多处理,更多的关注业务逻辑就行
更加灵活,但是需要开发者多多的操作相关事件,比如点击事件那就需要自定义接口,没有类似于ListView的addHaedView等方法在使用中用的多的就是有添加头部尾部 加载更多 下拉刷新(可以和系统的refreshlayout)一起使用

项目中我用的是easyRecyclerView 开源项目(自行github 挺好用) 主要是加载更多和下拉刷新实现了 添加头部尾部貌似不行 用这个LayoutManager来辅助实现 完全可以 因为EasyRecyclerView的加载更多等等解耦很好 都是Adpater来处理数据 解耦的好处 互不影响 真是其实厉害

正题
前面看到一篇博客
源地址
http://m.blog.csdn.net/blog/oushangfeng123/47435867

讲用LayoutManager来实现RecycleView的头部尾部添加,特意实现了一遍 它里面稍微分析了一下 看了一下源码 我就不分析了 看他的原帖去吧

先看个效果 都是添加了头部和尾部

RecyclerViewLayoutManager分析 添加头部尾部_第1张图片
GIF.gif

上Activity代码

public class RecyclerViewMainActivity extends ActionBarActivity {

private android.widget.Button bt1;
private android.widget.Button bt2;
private android.widget.Button bt3;
private RecyclerView rcv;
private GridLayoutManager gridLayoutManager;
private StaggeredGridLayoutManager staggeredGridLayoutManager;
List lists=new ArrayList();
private LinearLayoutManager linearLayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_recycler_view_main);
    this.rcv = (RecyclerView) findViewById(R.id.rcv);

    this.bt3 = (Button) findViewById(R.id.bt3);
    this.bt2 = (Button) findViewById(R.id.bt2);
    this.bt1 = (Button) findViewById(R.id.bt1);

    bt2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            gridLayoutManager = new GridLayoutManager(RecyclerViewMainActivity.this, 2);
            lists.clear();
            for(int i=0 ; i<20 ; i++){
                lists.add("123"+i);
            }
            RecycleViewGridAdapter recycleViewAdapter = new RecycleViewGridAdapter(lists);
            LayoutInflater layoutInflater = getLayoutInflater();
            View view = layoutInflater.inflate(R.layout.item_top, null);
            recycleViewAdapter.addHeadView(view);
            View view1 = layoutInflater.inflate(R.layout.item_foot, null);
            recycleViewAdapter.addFootView(view1);

            //如果添加了头部或者尾部 就需要做相关的SpanSize的修改
            recycleViewAdapter.setChangeGridLayoutManager(new RecycleViewGridAdapter.ChangeGridLayoutManagerSpance() {
                @Override
                public void change(final int size, final boolean isAddHead, final boolean isAddFoot) {
                    gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                        @Override
                        public int getSpanSize(int position) {
                            int spanSzie = 1;
                            if (isAddHead) {
                                if (position == 0) {
                                    spanSzie = gridLayoutManager.getSpanCount();
                                }
                            }

                            if (isAddFoot) {
                                if (position == size) {
                                    spanSzie = gridLayoutManager.getSpanCount();
                                }
                            }
                            return spanSzie;
                        }
                    });
                }
            });
            rcv.setLayoutManager(gridLayoutManager);
            rcv.setAdapter(recycleViewAdapter);
        }
    });


    bt3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            staggeredGridLayoutManager=new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
            lists.clear();
            for(int i=0 ; i<20 ; i++){
                lists.add("123"+i);
            }
            RecycleViewStageredAdapter recycleViewStageredAdapter = new RecycleViewStageredAdapter(lists);
            recycleViewStageredAdapter.addHeadView(R.layout.item_top);
            recycleViewStageredAdapter.addFootView(R.layout.item_top);

            rcv.setLayoutManager(staggeredGridLayoutManager);
            rcv.setAdapter(recycleViewStageredAdapter);
        }
    });

    bt1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
             linearLayoutManager=new LinearLayoutManager(RecyclerViewMainActivity.this);
            linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

            lists.clear();
            for(int i=0 ; i<20 ; i++){
                lists.add("123"+i);
            }
            RecycleviewLinearAdapter recycleviewLinearAdapter=new RecycleviewLinearAdapter(lists);

            LayoutInflater layoutInflater = getLayoutInflater();
            View view = layoutInflater.inflate(R.layout.item_top, null);
            recycleviewLinearAdapter.addHeadView(view);
            View view1 = layoutInflater.inflate(R.layout.item_foot, null);
            recycleviewLinearAdapter.addFootView(view1);

            rcv.setLayoutManager(linearLayoutManager);
            rcv.setAdapter(recycleviewLinearAdapter);

        }
    });
}
}    

然后是各个ViewHolder 整体结构图

RecyclerViewLayoutManager分析 添加头部尾部_第2张图片
Paste_Image.png

RecycleviewLinearAdapter 代码

public class RecycleviewLinearAdapter extends RecyclerView.Adapter {
private static final int TYPE_HEADER = 0, TYPE_ITEM = 1, TYPE_FOOT = 2;
public List mDatas;
private View headView;
private View footView;
private int headViewSize = 0;
private int footViewSize = 0;
private boolean isAddFoot = false;
private boolean isAddHead = false;

public RecycleviewLinearAdapter(List mDatas) {
    this.mDatas = mDatas;
}

public void addHeadView(View view) {
    headView = view;
    headViewSize = 1;
    isAddHead = true;
}

public void addFootView(View view) {
    footView = view;
    footViewSize = 1;
    isAddFoot = true;
}

@Override
public int getItemViewType(int position) {
    int type = TYPE_ITEM;
    if (headViewSize == 1 && position == 0) {
        type = TYPE_HEADER;
    } else if (footViewSize == 1 && position == getItemCount() - 1) {
        //最后一个位置
        type = TYPE_FOOT;
    }
    return type;
}


@Override
public LinearViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = null;
    switch (viewType) {
        case TYPE_HEADER:
            view = headView;
            break;

        case TYPE_ITEM:
            view = View.inflate(parent.getContext(), R.layout.item_icon, null);
            break;

        case TYPE_FOOT:
            view = footView;
            break;
    }
    return new LinearViewHolder(view);
}

@Override
public void onBindViewHolder(LinearViewHolder holder, int position) {
}

@Override
public int getItemCount() {
    return mDatas.size()+headViewSize+footViewSize;
}
}

class LinearViewHolder extends RecyclerView.ViewHolder {
public LinearViewHolder(View itemView) {
    super(itemView);
}
}

RecycleViewGridAdapter 代码

public class RecycleViewGridAdapter extends RecyclerView.Adapter {
private static final int TYPE_HEADER = 0, TYPE_ITEM = 1, TYPE_FOOT = 2;

public List mDatas;
private View headView;
private View footView;
private int headViewSize = 0;
private int footViewSize = 0;
private ChangeGridLayoutManagerSpance changeGridLayoutManager;
private boolean isAddFoot=false;
private boolean isAddHead=false;




public interface ChangeGridLayoutManagerSpance{
    public void change(int size, boolean isAddHead, boolean isAddFoot);
}
//提供接口给 让LayoutManager根据添加尾部 头部与否来做判断 显示头部与底部的SpanSize要在添加头部和尾部之后 
public void setChangeGridLayoutManager(ChangeGridLayoutManagerSpance changeGridLayoutManager){
    this.changeGridLayoutManager=changeGridLayoutManager;
    changeGridLayoutManager.change(getItemCount()-1,isAddHead,isAddFoot);
}

public RecycleViewGridAdapter(List datas) {
    mDatas = datas;
}

public void addHeadView(View view) {
    headView = view;
    headViewSize = 1;
    isAddHead=true;
}

public void addFootView(View view) {
    footView = view;
    footViewSize = 1;
    isAddFoot=true;
}

@Override
public int getItemViewType(int position) {
    int type = TYPE_ITEM;

    if (headViewSize==1 && position == 0) {
        type = TYPE_HEADER;
    } else if (footViewSize==1 && position == getItemCount()-1) {
        //最后一个位置
        type = TYPE_FOOT;
    }
    return type;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = null;
    switch (i) {
        case TYPE_HEADER:
            view = headView;
            break;

        case TYPE_ITEM:
            view = View.inflate(viewGroup.getContext(), R.layout.item_icon, null);
            break;

        case TYPE_FOOT:
            view =footView;
            break;
    }
    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

}
@Override
public int getItemCount() {
    return mDatas.size() + headViewSize + footViewSize;
}
}

class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView) {
    super(itemView);
}
}

RecycleViewStageredAdapter 代码

public class RecycleViewStageredAdapter extends RecyclerView.Adapter{
private static final int TYPE_HEADER = 0, TYPE_ITEM = 1, TYPE_FOOT = 2;

public List mDatas;
private int headViewid;
private int headViewSize;
private boolean isAddHead;
private int footViewid;
private int footViewSize;
private boolean isAddFoot;

public RecycleViewStageredAdapter(List mDatas) {
    this.mDatas = mDatas;
}

public void addHeadView(int view) {
    headViewid = view;
    headViewSize = 1;
    isAddHead=true;
}

public void addFootView(int view) {
    footViewid = view;
    footViewSize = 1;
    isAddFoot=true;
}

@Override
public MyViewHolder1 onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = null;
    switch (i) {
        case TYPE_HEADER:
            view = LayoutInflater.from(viewGroup.getContext()).inflate(headViewid, viewGroup, false);
            break;

        case TYPE_ITEM:
            view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_icon, viewGroup, false);
            break;

        case TYPE_FOOT:
            view = LayoutInflater.from(viewGroup.getContext()).inflate(footViewid, viewGroup, false);
            break;
    }
    return new MyViewHolder1(view);
}

@Override
public void onBindViewHolder(MyViewHolder1 myViewHolder, int i) {
    switch (myViewHolder.getItemViewType()) {
        case TYPE_HEADER:

            // 获取cardview的布局属性,记住这里要是布局的最外层的控件的布局属性,如果是里层的会报cast错误
            StaggeredGridLayoutManager.LayoutParams clp = (StaggeredGridLayoutManager.LayoutParams) myViewHolder.cardview.getLayoutParams();
            // 最最关键一步,设置当前view占满列数,这样就可以占据两列实现头部了
            if(clp!=null)
                clp.setFullSpan(true);
            break;

        case TYPE_ITEM:
            ViewGroup.LayoutParams layoutParams=myViewHolder.cardview.getLayoutParams();
            layoutParams.height= (int) ((i%mDatas.size()+1)*20);
            myViewHolder.cardview.setLayoutParams(layoutParams);
            break;

        case TYPE_FOOT:
            // 获取cardview的布局属性,记住这里要是布局的最外层的控件的布局属性,如果是里层的会报cast错误
            StaggeredGridLayoutManager.LayoutParams clp1 = (StaggeredGridLayoutManager.LayoutParams) myViewHolder.cardview.getLayoutParams();
            // 最最关键一步,设置当前view占满列数,这样就可以占据两列实现头部了
            clp1.setFullSpan(true);

            break;
    }
}

@Override
public int getItemViewType(int position) {

    int type = TYPE_ITEM;
    if (headViewSize==1 && position == 0) {
        type = TYPE_HEADER;
    } else if (footViewSize==1 && position == getItemCount()-1) {
        //最后一个位置
        type = TYPE_FOOT;
    }
    return type;
}

@Override
public int getItemCount() {
    return mDatas.size()+headViewSize+footViewSize;
}
}

class MyViewHolder1 extends RecyclerView.ViewHolder{
public CardView cardview;
public MyViewHolder1(View itemView) {
    super(itemView);
    cardview = (CardView) itemView.findViewById(R.id.cv);
}
}

发现其实都很长不差不多太多 LinearLayoutManager没啥难点
GridLayoutManager 是要设置SpanSize每行的占位大小

StaggerLayoutManager 就是要获取StaggerLayoutManager的LayoutParams 的setFullSpan 方法来设置占位宽度

贴一贴布局代码

item





top






foot





你可能感兴趣的:(RecyclerViewLayoutManager分析 添加头部尾部)