使用RecyclerView实现带Header和Footer的GridView

本文介绍如何利用RecyclerView组件实现具有Header和Footer的GridView功能,详细解释了RecyclerView的优势、实现原理及代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GridVIew不能和ListView一样添加Header和Footer相信都给大家带来了不小的麻烦吧。今天我为大家带来了使用RecyclerView实现带Header和Footer的GridView。

1.首先我们来了解一下RecyclerView

RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,它的优点大致有  

封装了ViewHolder简化了使用

2 使用LayoutManager管理布局,让开发开发者可以自由的管理直接的布局(官方提供的LinearLayoutManager和GridLayoutManager就可以实现横向和纵向的列表和网格布局,StaggeredGridLayoutManager可以实现瀑布流布局,还可以通过自定义LayoutManager实现自己个性化的布局

3 使用ItemDecoration管理VIew之间的分割区域,让开发者可以轻易的管理和自定义分隔区域

简单的说,RecyclerView就是ListView和GridView的综合进化版。当然,RecyclerView毕竟是新的控件,还是有不少问题的。例如有很多人都提到过,RecyclerView的使用不当会导致滑动非常的卡顿;Item的高度不一定时,获取滑动的距离将会异常的困难;嵌套在SrcollView中使用的时候,也会比ListView和GridView复杂……


2.现在来说说RecyclerView实现带Header和Footer的GridView的原理

其实说来非常的简单。GridLayoutManager可以通过setSpanSizeLookup来控制Item占据多少列,那我们只要把Header和Footer当作普通的Item,然后让其占据一行中所有的列久行了。

MainActivity的代码:

package recycleview.sgn.com.recyclerview;

import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private View Header;
    private View Footer;
    private Adapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
        Header = getLayoutInflater().inflate(R.layout.header,null);
        Footer = getLayoutInflater().inflate(R.layout.footer,null);
        //初始化适配器,并传人Header和Footer
        adapter = new Adapter(MainActivity.this,Header,Footer);
        List<String> list = new ArrayList<String >();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        list.add("6");
        adapter.addAll(list);
        //初始化布局管理器
        final GridLayoutManager lm = new GridLayoutManager(this,2);

        /*
        *设置SpanSizeLookup,它将决定view会横跨多少列。这个方法是为RecyclerView添加Header和Footer的关键。
        *当判断position指向的View为Header或者Footer时候,返回总列数( lm.getSpanCount()),即可让其独占一行。
        */
        lm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                return adapter.isHeader(position) ? lm.getSpanCount() : (adapter.isFooter(position) ? lm.getSpanCount() : 1);
            }
        });
        //设置布局管理器
        recyclerView.setLayoutManager(lm);
        //绘制item间的分割线,
        recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                int postion = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewAdapterPosition();
                if (adapter.isHeader(postion) || adapter.isFooter(postion)) {
                    outRect.set(0, 0, 0, 20);
                } else {
                    outRect.set(20, 20, 20, 20);
                }
            }
        });

        recyclerView.setAdapter(adapter);


    }

}


Adapter代码:

package recycleview.sgn.com.recyclerview;

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 org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by liujinhua on 15/9/10.
 */
public class Adapter extends RecyclerView.Adapter<Adapter.VH> {

    private static final int ITEM_VIEW_TYPE_HEADER = 0;
    private static final int ITEM_VIEW_TYPE_ITEM = 1;
    private static final int ITEM_VIEW_TYPE_FOOTER = 2;
    List<String> data;
    View header;
    View footer;
    Context context;

    public Adapter(Context context, View header, View footer) {
        data = new ArrayList<String>();
        this.header = header;
        this.footer = footer;
        this.context = context;
    }

    //返回View的类别
    @Override
    public int getItemViewType(int position) {
        if (isHeader(position)) {
            return ITEM_VIEW_TYPE_HEADER;
        }
        if (isFooter(position)) {
            return ITEM_VIEW_TYPE_FOOTER;
        }
        return ITEM_VIEW_TYPE_ITEM;
    }



    //创建ViewHolder的时候要
    @Override
    public VH onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case ITEM_VIEW_TYPE_HEADER:
                return new VH(header);
            case ITEM_VIEW_TYPE_FOOTER:
                return new VH(footer);
            default:
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
                return new VH(view);
        }
    }

    //绑定数据
    @Override
    public void onBindViewHolder(VH vh, int i) {
        //如果时Header和Footer的时候直接返回,Header和Footer的操作,可以在Activity中进行
        if (isHeader(i) || isFooter(i)) {
            return;
        }

        //绑定数据时要注意,因为多出Header在前,所以需要-1
        ((TextView) vh.itemView).setText(data.get(i - 1));
    }


    //获取Item的数量,因为添加了Header和Footer,View的数量应该加2
    @Override
    public int getItemCount() {
        return data.size()  + 2;
    }

    public void addAll(List<String> data) {
        this.data.addAll(data);
        notifyDataSetChanged();

    }

    public class VH extends RecyclerView.ViewHolder {

        public VH(View itemView) {
            super(itemView);
        }

    }

    public boolean isHeader(int position) {
        return position == 0;
    }

    public boolean isFooter(int position) {
        return position == (data.size() + 1);
    }

}


效果图:



这是源代码



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值