Recycle view的用法

这篇博客介绍了RecyclerView的基本用法,包括在build.gradle中引入依赖,创建对象,设置线性显示规则和适配器。重点讲解了RecyclerView的点击事件处理,以及如何添加分割线。博主分享了一个开源的Divider解决方案,并提供了自封装的Adapter,用于实现ListView的header和footer功能,还给出了多套布局加载的Demo链接。

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

RecyclerView 将所有的显示规则交给一个叫 LayoutManager 的类去完成了。LayoutManager 是一个抽象类,系统已经为我们提供了三个默认的实现类,分别是 LinearLayoutManager 、 GridLayoutManager 、 StaggeredGridLayoutManager,从名字我们就能看出来了,分别是,线性显示、网格显示、瀑布流显示。
Recycle view和Listviet、GridView类似,都是可以显示同一种类型的View的集合控件。
首先看最简单的用法:

1.在build.gradle文件中加入
compile 'com.android.support:recyclerview-v7:24.0.0'
2.创建对象
RecyclerView rv_main_activity = (RecyclerView) findViewById(R.id.rv_main_activity);
3.设置显示规则,这里是用线性显示
rv_main_activity.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
4.设置适配器
rv_main_activity.setAdapter(linearLayoutAdapter);

适配器是用来这是每个item显示内容的。通常,我们写Listview的适配器的时候是先继承BaseAdapter,实现四个抽象方法,创建一个静态的Viewholder。
而Recycleview也是类似的步骤,首先继承RecycleView.Adapter类,实现3个抽象方法,创建一个静态的ViewHolder,继承Recycleview.ViewHolder 类。
下面直接上代码:

/**
 * 作者:sufferable 17/2/10 14:24
 * 邮箱:xsxdg666@gmail.com
 */
public class LinearLayoutAdapter extends RecyclerView.Adapter<LinearLayoutAdapter.MyHolder> {
    private ArrayList<String> mList;
    private Context mContext;

    public LinearLayoutAdapter(ArrayList<String> list, Context context) {
        mList = list;
        mContext = context;
    }

    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = null;
        RecyclerView.ViewHolder holder = null;
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        view = View.inflate(mContext, R.layout.item_linearlayout, null);
        view.setLayoutParams(layoutParams);
        return new MyHolder(view);
    }

    @Override
    public void onBindViewHolder(MyHolder holder, final int position) {
        holder.tv_item.setText(mList.get(position));
        holder.tv_item.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mOnRecyclerViewItemClickListener != null) {
                    mOnRecyclerViewItemClickListener.onItemClickListener(view, position);
                }
            }
        });
    }


    //返回item的条数
    @Override
    public int getItemCount() {
        return mList.size();
    }

    public class MyHolder extends RecyclerView.ViewHolder {
        TextView tv_item;

        public MyHolder(View itemView) {
            super(itemView);
            tv_item = (TextView) itemView.findViewById(R.id.tv_item_left);
        }
    }

    private OnRecyclerViewItemClickListener mOnRecyclerViewItemClickListener;

    public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener recyclerViewItemClickListener) {
        this.mOnRecyclerViewItemClickListener = recyclerViewItemClickListener;
    }

    public interface OnRecyclerViewItemClickListener {
        void onItemClickListener(View View, int positon);
    }
}
因为Recycleview没有OnItemClickListener方法,所以点击事件可以直接写在Adapter里面,也可以像我上面代码写的那样,把点击事件做成接口暴露出去:
linearLayoutAdapter.setOnRecyclerViewItemClickListener(mOnRecyclerViewItemClickListener);
 LinearLayoutAdapter.OnRecyclerViewItemClickListener mOnRecyclerViewItemClickListener = new LinearLayoutAdapter.OnRecyclerViewItemClickListener() {
        @Override
        public void onItemClickListener(View View, int positon) {
            Intent intent = new Intent();
            if (positon == 0){
                intent.setClass(mContext,HeaderFooterActivity.class);
                startActivity(intent);
            }else if (positon == 1){
                intent.setClass(mContext,DividerActivity.class);
                startActivity(intent);
            }else if (positon == 2){
                intent.setClass(mContext,ManylayoutActivity.class);
                startActivity(intent);
            }else if (positon == 3){
                intent.setClass(mContext,GridLayoutActivity.class);
                startActivity(intent);
            }else if (positon ==4){
                intent.setClass(mContext,StaggeredGridLayoutActivity.class);
                startActivity(intent);
            }
        }
    };

加载数据、点击事件好了,运行起来发现没有分割线,恩简单,在XML文件中设置就好了还能同时设置divider的高度
android:divider=”@android:color/black”
android:dividerHeight=”2dp”
为什么没效果呢?因为在Recycleview中,要实现设置分割线的颜色和高度要麻烦一点,需要自己继承RecycleView.ItemDecoration来实现想要实现的方法

我在网上找了一个开源的应该能满足大部分情况的需求:

Divider.java 用 demo 可以查看:Github 【自定义 Divider 使用

在使用Listview的时候大家经常使用addHeader和addFooter方法,但是发现recycle view没有这两个方法,因为在Recycleview中没有这两个概念,Recycleview是创建多个Viewholder加载多套布局的,不过如果是像我这样懒的人用习 惯了这两个方法,下面就是我封装的adapter,其实原理就是如果position == 0 或者等于list的长度就加载对应的布局,我只是做了一个封装,下面上代码:
/**
 * 作者:sufferable 17/2/10 16:04
 * 邮箱:xsxdg666@gmail.com
 */
public class HeaderFooterAdapter  extends RecyclerView.Adapter<HeaderFooterAdapter.MyHolder> {
    private Context mContext;
    private ArrayList mList;
    private RecyclerView mRecyclerView;
    //用来判断是头布局还是列表还是尾布局
    private int TYPE_NORMAL = 1000;
    private int TYPE_HEADER = 1001;
    private int TYPE_FOOTER = 1002;
    private View VIEW_FOOTER;
    private View VIEW_HEADER;
    public HeaderFooterAdapter(Context context, ArrayList list) {
        mContext = context;
        mList = list;
    }
    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_FOOTER) {
            //尾巴
            return new MyHolder(VIEW_FOOTER);
        } else if (viewType == TYPE_HEADER) {
            //头
            return new MyHolder(VIEW_HEADER);
        } else {
            //列表
            return new MyHolder(getLayout(R.layout.item_linearlayout));
        }
    }
    @Override
    public void onBindViewHolder(MyHolder holder, int position) {
        if (!isHeaderView(position) && !isFooterView(position)) {
            if (headerView()) position--;
            holder.mTextView_right.setText(mList.get(position) + "");
            holder.mTextView_left.setText("列表");
        }
    }
    @Override
    public int getItemCount() {
        int count = (mList == null ? 0 : mList.size());
        if (VIEW_FOOTER != null) {
            count++;
        }
        if (VIEW_HEADER != null) {
            count++;
        }
        return count;
    }
    @Override
    public int getItemViewType(int position) {
        if (isHeaderView(position)) {
            return TYPE_HEADER;
        } else if (isFooterView(position)) {
            return TYPE_FOOTER;
        } else {
            return TYPE_NORMAL;
        }
    }
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        try {
            if (mRecyclerView == null && mRecyclerView != recyclerView) {
                mRecyclerView = recyclerView;
            }
            ifGridLayoutManager();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void addHeaderView(View headerView) {
        if (headerView()) {
            throw new IllegalStateException("hearview has already exists!");
        } else {
            //避免出现宽度自适应
            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            headerView.setLayoutParams(params);
            VIEW_HEADER = headerView;
            ifGridLayoutManager();
            notifyItemInserted(0);
        }
    }
    public void addFooterView(View footerView) {
        if (footerView()) {
            throw new IllegalStateException("footerView has already exists!");
        } else {
            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            footerView.setLayoutParams(params);
            VIEW_FOOTER = footerView;
            ifGridLayoutManager();
            notifyItemInserted(getItemCount() - 1);
        }
    }
    private void ifGridLayoutManager() {
        if (mRecyclerView == null) return;
        final RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            final GridLayoutManager.SpanSizeLookup originalSpanSizeLookup =
                    ((GridLayoutManager) layoutManager).getSpanSizeLookup();
            ((GridLayoutManager) layoutManager).setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return (isHeaderView(position) || isFooterView(position)) ?
                            ((GridLayoutManager) layoutManager).getSpanCount() :
                            1;
                }
            });
        }
    }
    private View getLayout(int layoutId) {
        return LayoutInflater.from(mContext).inflate(layoutId, null);
    }
    private boolean headerView() {
        return VIEW_HEADER != null;
    }
    private boolean isHeaderView(int position) {
        return headerView() && position == 0;
    }
    private boolean isFooterView(int position) {
        return footerView() && position == getItemCount() - 1;
    }
    public boolean footerView() {
        return VIEW_FOOTER != null;
    }
    public static class MyHolder extends RecyclerView.ViewHolder{
        TextView mTextView_left;
        TextView mTextView_right;
        public MyHolder(View itemView) {
            super(itemView);
             mTextView_left = (TextView) itemView.findViewById(R.id.tv_item_left);
             mTextView_right = (TextView) itemView.findViewById(R.id.tv_item_rigtht);
        }
    }
}
使用的时候:
RecyclerView rv_main_activity = (RecyclerView) findViewById(R.id.rv_main_activity);
        rv_main_activity.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        HeaderFooterAdapter headerFooterAdapter = new HeaderFooterAdapter(mContext, list);
        rv_main_activity.setAdapter(headerFooterAdapter);
        View footInflate = LayoutInflater.from(this).inflate(R.layout.item_footer, null);
        View HeaderInflate = LayoutInflater.from(this).inflate(R.layout.item_header, null);
        headerFooterAdapter.addFooterView(footInflate);
        headerFooterAdapter.addHeaderView(HeaderInflate);
然后下面的就跟listview的头布局尾布局一样使用了。既然写了这个就顺便把Recycleview加载多套布局的代码也发出来吧:
/**
 * 作者:sufferable 17/2/10 17:21
 * 邮箱:xsxdg666@gmail.com
 */
public class ManylayoutAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final int TEMP_1 = 1000;
    private final int TEMP_2 = 1001;
    private final int TEMP_3 = 1002;
    private final int TEMP_4 = 1003;
    private ArrayList mList;
    private Context mContext;

    public ManylayoutAdapter(ArrayList list, Context context) {
        mList = list;
        mContext = context;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = null;
        RecyclerView.ViewHolder holder = null;
        LinearLayout.LayoutParams layoutParams =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
        switch (viewType){
            case TEMP_1:
                view = View.inflate(mContext,R.layout.item_one,null);
                view.setLayoutParams(layoutParams);
                holder = new VH1(view);
                return holder;
            case TEMP_2:
                view = View.inflate(mContext,R.layout.item_two,null);
                view.setLayoutParams(layoutParams);
                holder = new VH2(view);
                return holder;
            case TEMP_3:
                view = View.inflate(mContext,R.layout.item_three,null);
                view.setLayoutParams(layoutParams);
                holder = new VH3(view);
                return holder;
            default:
                view = View.inflate(mContext,R.layout.item_linearlayout,null);
                view.setLayoutParams(layoutParams);
                holder = new VH4(view);
                return holder;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (getItemViewType(position)){
            case TEMP_1:
                VH1 vh1 = (VH1) holder;
                vh1.mTextView.setText("第一种布局");
                break;
            case TEMP_2:
                VH2 vh2 = (VH2) holder;
                //设置数据
                vh2.image.setImageResource(R.drawable.item_1);
                break;
            case TEMP_3:
                VH3 vh3 = (VH3) holder;
                vh3.mTextView.setText("第三种布局");
                break;
            default:
                VH4 vh4 = (VH4) holder;
                vh4.mTextView_left.setText("左边");
                vh4.mTextView_reght.setText("右边");
                break;
        }

    }


    @Override
    public int getItemViewType(int position) {
        if (position >= 0 && position < 10) {
            return TEMP_1;
        } else if (position >= 10 && position < 20) {
            return TEMP_2;
        } else if (position >= 20 && position < 30) {
            return TEMP_3;
        } else  {
            return TEMP_4;
        }


    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    public static class VH1 extends RecyclerView.ViewHolder {
        TextView mTextView;

        public VH1(View itemView) {
            super(itemView);
            mTextView = (TextView) itemView.findViewById(R.id.text);
        }
    }

    public static class VH2 extends RecyclerView.ViewHolder {
        ImageView image;

        public VH2(View itemView) {
            super(itemView);
            image = (ImageView) itemView.findViewById(R.id.image);
        }
    }

    public static class VH3 extends RecyclerView.ViewHolder {
        TextView mTextView;
        ImageView mImageView;
        public VH3(View itemView) {
            super(itemView);
            mTextView = (TextView) itemView.findViewById(R.id.text);
            mImageView = (ImageView) itemView.findViewById(R.id.image);
        }
    }
    public static class VH4 extends RecyclerView.ViewHolder {
        TextView mTextView_reght;
        TextView mTextView_left;

        public VH4(View itemView) {
            super(itemView);
            mTextView_reght = (TextView) itemView.findViewById(R.id.tv_item_rigtht);
            mTextView_left = (TextView) itemView.findViewById(R.id.tv_item_left);
        }
    }
}
原理跟前面封装的添加头尾布局是一样的,还有网格状布局、瀑布流,下面直接上Dome的链接,用的上的朋友下载后别忘了打分。代码里面有我的邮箱,有问题欢迎大家多沟通交流。
dome链接http://download.youkuaiyun.com/detail/sufferable/9755139
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值