谈谈RecyclerView的用法与添加Header的个人理解

随着Android版本的更新,出现了越来越多的新控件,作为一名Android程序员很有必要去关心这些东西,毕竟面试的时候很多面试官喜欢问。大家肯定都知道ListView这个控件,因为很多地方都需要用到它。自Android 5.0之后,谷歌公司推出了RecycleVIew控件,这个滑动控件的功能非常强大,既能实现ListView的功能,也能实现GridView的效果,下面就让我们一起去看看这个控件如何使用吧。
首先我们先来看看他是怎么实现ListView的功能吧,不多说,直接上代码:

public class RecyclerViewActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private LinearLayoutManager mLayoutManager;
    private RecyclerViewAdapter mRecyclerViewAdapter;
    private List<JavaBean> mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view);
        mRecyclerView = (RecyclerView) findViewById(R.id.activity_recycler_view);
        initData();
         mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerViewAdapter = new RecyclerViewAdapter(this, mList, mRecyclerView);
        mRecyclerView.setAdapter(mRecyclerViewAdapter);
    }

    private void initData() {
        mList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            mList.add(new JavaBean("sorelion" + i));
            mList.add(new JavaBean("sorelion" + i));
        }
    }
}

适配器代码

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int TYPE_HEADER = 0;
    private static final int TYPE_NORMAL = 1;
    private final RecyclerView mRecyclerView;
    private List<JavaBean> mlist;
    private Context mContext;
    private View mHeaderView;

    public RecyclerViewAdapter(Context context, List<JavaBean> list, RecyclerView mRecyclerView) {
        this.mlist = list;
        this.mContext = context;
        this.mRecyclerView = mRecyclerView;
        mHeaderView = LayoutInflater.from(mContext).inflate(R.layout.item1, mRecyclerView, false);
    }

    @Override
    public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_HEADER) {
            return new RecyclerHolder(mHeaderView);
        } else {
            View view = LayoutInflater.from(mContext).inflate(R.layout.item, parent, false);
            RecyclerHolder holder = new RecyclerHolder(view);
            return holder;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (position == 0) {
            return;
        } else {
            ((RecyclerHolder) holder).text.setText(mlist.get(position).getName());
        }
    }

    @Override
    public int getItemCount() {
        return mlist == null ? 0 : mlist.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return TYPE_HEADER;
        }
        return TYPE_NORMAL;
    }

    class RecyclerHolder extends RecyclerView.ViewHolder {
        TextView text;
        public RecyclerHolder(View itemView) {
            super(itemView);
            if (itemView == mHeaderView) return;
            text = (TextView) itemView.findViewById(R.id.text);
        }
    }

我们跑起来看看效果

这里写图片描述
是不是和ListView一样呢,那么下面我们来看看双列会有什么效果呢?
我们换一个LayoutManage就可以达到效果.

mLayoutManager = new GridLayoutManager(this, 2);

这里写图片描述

问题出来了,怎么成这样了?仔细分析一下就会知道,因为在我们上面的代码中,当position为0的时候,我们会填充一个头布局,其他情况填充正常的布局,所以这种情况的出现是可以理解的,但是这明显不是我们想要的效果,怎么办呢?
这时候我们需要重写一个方法:

 gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return getItemViewType(position) == TYPE_HEADER
                            ? gridManager.getSpanCount() : 1;
                }
            });

怎么理解呢?我的理解就是判断当前的条目是不是头布局,是头布局,那么就占据相应的单元格(根据GridManager初始化时的参数),正常就只占据一个单元格,借鉴大神的建议,我决定把这个方法这样放:

@Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return getItemViewType(position) == TYPE_HEADER
                            ? gridManager.getSpanCount() : 1;
                }
            });
        }
    }

跑起来在看看效果
这里写图片描述

哈哈,终于完美解决问题了,可能有些人对下面的一段代码就不理解了,为什么我position等于1的时候不需要判断呢,明明一个header布局相当于占据了两个position的位置啊。

 @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (position == 0) {
            return;
        } else {
            ((RecyclerHolder) holder).text.setText(mlist.get(position).getName());
        }
    }

对于这块,我也只是稍微翻了翻源码(毕竟全英文,上班没那么多时间去研究),稍微理解了一下,有兴趣的可以自己去看看源码,去揭开它的神秘面纱吧。有了这些思路,显示多类型的条目是不是有了思路呢?当然你也可以像ListView那样,封装自己的addheader和addfoot方法,究竟怎么玩,那就看你了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值