当ListView遇上RecyclerView, ListView将甘拜下风

通过本篇博客,你将学到以下知识点

①RecyclerView与ListView相比它的优点
②RecyclerView的初步用法
③RecyclerView的Adapter的用法
④给RecyclerView增加条目点击事件

1.RecyclerView是什么?

  RecylerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字recylerview即回收view也可以看出。看到这也许有人会问,不是已经有ListView了吗,为什么还要RecylerView呢?这就牵扯到第二个问题了。

2.RecyclerView的优点是什么?

 根据官方的介绍RecylerView是ListView的升级版,既然如此那RecylerView必然有它的优点,现就RecylerView相对于ListView的优点罗列如下:

①RecylerView封装了viewholder的回收复用,也就是说RecylerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的 逻辑被封装了,写起来更加简单。

②提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecylerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还有StaggeredGridLayoutManager等),也就是说RecylerView不再拘泥于ListView的线性展示方式,它也可以实现GridView的效果等多种效果。你想控制Item的分隔线,可以通过继承RecylerView的ItemDecoration这个类,然后针对自己的业务需求去抒写代码。

③可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecylerView有其自己默认的实现。

3.RecyclerView的用法

目前SDK中提供了三种自带的LayoutManager:

LinearLayoutManager:线性布局,横向或者纵向滑动列表
GridLayoutManager:表格布局
StaggeredGridLayoutManager:流式布局,例如瀑布流效果

效果展示:
可对item进行增加和删除。
这里写图片描述

实现步骤:

 1.创建一个继承于RecyclerView.Adapter的子类作为RecyclerView的适配器
 2.创建一个继承于RecyclerView.ViewHolder的子类作为当前适配器的viewholder 
 并将其作为RecyclerView.Adapter的泛型来使用(统一开发规范) 
3.实现当前适配器中的方法
4.加载布局,并初始化MyViewHolder,然后通过onCreateViewHolder返回 
5.通过onBindViewHolder方法填充控件

简单的RecyclerView使用方法:

一.添加依赖
这里写图片描述

二、编写代码
1.添加完依赖之后,就开始写代码了,与ListView用法类似,也是先在xml布局文件中创建一个RecyclerView的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview2"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

2.创建完布局之后在MainActivity中获取这个RecyclerView,并声明LayoutManager与Adapter,代码如下:

public class GridRecyclerViewActivity extends Activity {
    private RecyclerView recyclerView;

    private List<String> list;

    private RecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_grid);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerview2);
        list = new ArrayList<String>();
        adapter = new RecyclerViewAdapter(this, list);
        initEvent();
        //如果想要一个Grid布局的列表,只要声明LayoutManager为GridLayoutManager即可:
        GridLayoutManager layoutManager = new GridLayoutManager(this, 4);
        /**
         * listview样式的滑动方向由setOrientation方法决定
         * LinearLayout.VERTICAL:竖向滑动
         * LinearLayout.HORIZONTAL:横向滑动
         * GridLayoutManager构造方法中的第二个参数:
         * 当setOrientation为LinearLayout.VERTICAL时,参数代表列数
         * 当setOrientation为LinearLayout.HORIZONTAL,参数代表行数
         */
        layoutManager.setOrientation(LinearLayout.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);
        loadData();
    }

    private void initEvent() {
        adapter.setOnItemClickListener(new RecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                //TODO 处理点击事件
                list.add(position,"添加");
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onItemLongClick(View view, int position) {
                //TODO 处理长按事件
                list.remove(position);//长按删除
               // adapter.notifyDataSetChanged();
            adapter.notifyItemRemoved(position);
            }
        });
    }

    private void loadData() {
        for (int i = 0; i < 100; i++) {
            list.add(i + "");
        }
        adapter.notifyDataSetChanged();
    }
}

3.接下来的问题就是Adapter的创建:
①onCreateViewHolder()
这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
②onBindViewHolder()
这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。
③getItemCount()
这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。

public class RecyclerViewAdapter extends
        RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>
{
    private Context context;

    private List<String> list;

    private OnItemClickListener onItemClickListener;

    public RecyclerViewAdapter(Context context, List<String> list)
    {
        this.context = context;
        this.list = list;
    }

    //创建新View,被LayoutManager所调用
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View convertview = LayoutInflater.from(context).inflate(
                R.layout.adapter_recycler_view, parent, false);
        Log.i("info", "onCreateViewHolder");
        return new MyViewHolder(convertview);
    }

    // 填充控件(同listview中的getView()方法,只作控件的赋值业务)

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position)
    {
        //将数据与界面进行绑定的操作
        holder.tv.setText(list.get(position));
        holder.itemView.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (onItemClickListener != null)
                {
                    onItemClickListener.onItemClick(v, position);
                }
                Log.i("info", "itemView被点击了===>" + position);
            }
        });
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener()
        {
            @Override
            public boolean onLongClick(View v)
            {
                if (onItemClickListener != null)
                {
                    int pos = holder.getLayoutPosition();//TODO 该方法用于获得和更新当前的位置,防止错位
                    onItemClickListener.onItemLongClick(v, pos);
                }
                Log.i("info", "itemView被长按了===>" + position);
                // 长按的返回值:当返回true表示消费掉当前事件,会使后续的操作无法获取到该事件
                // 如果返回false,则可触发onClick监听
                return true;
            }
        });
    }

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

    /**
     * 继承于RecyclerView.ViewHolder的作用 1.统一开发规范 2.增强封装性
     */
    //自定义的ViewHolder,持有每个Item的的所有界面元素
    public class MyViewHolder extends RecyclerView.ViewHolder
    {
        private TextView tv;

        public MyViewHolder(View itemView)
        {
            super(itemView);
            tv = (TextView) itemView.findViewById(R.id.tv);
        }
    }

    public interface OnItemClickListener
    {
        // 点击回调方法
        void onItemClick(View view, int position);

        // 长按回调方法
        void onItemLongClick(View view, int position);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener)
    {
        this.onItemClickListener = onItemClickListener;
    }
}

不懂的可以再浏览下大神的博客,博客的连接是:http://blog.youkuaiyun.com/skykingf/article/details/50827141

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值