zoukankan      html  css  js  c++  java
  • Android开发——RecyclerView特性以及基本使用方法(一)

    0.  前言

    随着Android的发展,虽然ListView依旧重要,但RecyclerView确实越来越多的被大家使用。但显然并不能说RecyclerView就一定优于ListView,而是应该根据不同的需求选择最合适的进行使用。本篇将介绍我们为什么要使用RecyclerView,并且它的基本使用方法。

     本文原创,转载请注明出处为SEU_Calvin的博客


    1.  我们为什么要使用RecyclerView

    Google声称你可以RecyclerView看成是升级版的ListView,为什么ListView没有被遗弃呢?到底RecyclerView强在哪里了呢?

    其实如果你只想简单的使用滑动显示这个功能,并且想轻松的使用dividerheaderfooter或者点击事件这些功能,那么使用ListView是完全没有问题的。RecyclerView除了已经封装好的Item复用机制外,的重点应该放在灵活性上,高度的解耦,这使得RecyclerView能够实现深度的定制化,通过提供的不同LayoutManagerItemDecorationItemAnimator等可以实现很多的效果。

     1RecyclerView提供的三种布局管理器LayoutManager),可以无缝衔接ListViewGridView,瀑布流的实现也变得简单,滑动删除和长按交换只需要添加几个类就可以实现。

    2ListView只有一个notifyDatasetChanged方法,想要做局部刷新还是挺麻烦的,但是在RecyclerView中,有很多适配局部刷新的API

    3RecyclerView实现Item增删等动画效果时,因为有了ItemAnimator因此要比ListView简单的多。如果想定制Item之间的间隔,使用ItemDecoration也很方便。

    4)关于点击事件,没有像ListView那样现成的API,但是自己封装起来也不难,而且我们使用ListView时,如果item中有可点击组件,那么点击事件的冲突也是一个问题,而在RecyclerView中则把点击事件的控制权完全的交给开发者。

     

    2.  RecyclerView的简单使用

    2.1  Adapter中的实现

    public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
    //…
    }
    

    RecyclerViewAdapter需要继承RecyclerView.Adapter<RecyclerAdapter.ViewHolder>

    其中有几个比较重要的方法需要实现,分别如下所示:

      @Override
        public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
            if (TYPE_ITEM == viewType) {
                View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
                return new ViewHolder(v);
            } else {
                View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_footer, viewGroup, false);
                return new ViewHolder(view);
            }
        }
    
        @Override
        public void onBindViewHolder(ViewHolder viewHolder, int i) {
               viewHolder.textView.setText(mData.get(i) + i);
        }
    
        @Override
        public int getItemCount() {
            return mData.size();
        }
    

    其中onCreateViewHolder()将布局转化为View并传递给RecyclerView封装好的ViewHolder,为了展示RecyclerView中展示两种布局的方式,做了两种区分,即如果是RecyclerView的最后一个条目,则换一种布局展示。这里简单的设置两个布局xml只是背景颜色不同,因此可以返回一样的ViewHolder。而正常情况下可以新建另一个内部类FooterViewHolder extendsRecyclerView.ViewHolder,并在onCreateViewHolder()中进行区分返回。而这个例子中我们返回的ViewHolder是一个内部类。在其中进行控件的初始化。

    public class ViewHolder extends RecyclerView.ViewHolder{
            public TextView textView;
            public ViewHolder(View itemView) {
                super(itemView);
                textView = (TextView)itemView.findViewById(R.id.id_num);
            }
    }
    

    onCreateViewHolder(ViewGroup viewGroup, int viewType)中的第二个参数,就是进行类别区分的,和ListView类似,需要在Adapter内部重写getItemViewType(intposition) 方法,实现哪个位置需要加载哪种布局的逻辑。如下例中,如果是最后一个条目,则返回一个代号。用于onCreateViewHolder()方法中进行具体的布局加载。

    @Override
    public int getItemViewType(int position) {
        if (position + 1 == getItemCount()) {
            return TYPE_FOOTER;
        } else {
            return TYPE_ITEM;
        }
    }
    

    有了ViewHolder之后,接下来就是要将ViewHolder和数据给绑定到一起来,在必须要实现的第二个方法onBindViewHolder(ViewHolder viewHolder,int i)中则建立起ViewHolder中视图与数据的关联。参数一个为对应的ViewHolder,一个为对应的位置。显然如果需要展示不同的布局,在onBindViewHolder()中通过判断viewHolder instanceof ViewHolder进行区分,对不同的布局中不同视图进行不同的数据关联

    最后getItemCount()是告知RecycleView,此Adapter到底要处理多少个对象。


    2.2  Activity中的实现

    mRcList = (RecyclerView) findViewById(R.id.rc_list);
    mLayoutManager = new LinearLayoutManager(this);
    mRcList.setLayoutManager(mLayoutManager);
    mRcList.setHasFixedSize(true);
    mSpinner = (Spinner) findViewById(R.id.spinner);
            mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    if (position == 0) {
                        mRcList.setLayoutManager(new LinearLayoutManager(MainActivity.this));
                        //设置分隔线
                        mRcList.addItemDecoration(new DividerItemDecoration(MainActivity.this, DividerItemDecoration.VERTICAL));
                    } else if (position == 1) {
                        mRcList.setLayoutManager(new GridLayoutManager(MainActivity.this, 3));
                        mRcList.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
                    }else if(position == 2){
                        //代表横着有10行
                        mRcList.setLayoutManager(new StaggeredGridLayoutManager(10,StaggeredGridLayoutManager.HORIZONTAL));
                        mRcList.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
                    }
                }
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                }
            });
    

    这里需要说明的是,现在SDK提供了三种LayoutManager可以提供给RecyclerView使用,分别为LinearLayoutManagerGridLayoutManagerStaggeredGridLayoutManager。本例中使用一个Spinner实现一个动态的切换效果。

    在设置的分隔线时,LinearLayoutManager设置为了系统默认的分隔线,如12行所示。如果想自定义,则可以在style中加入<item name="android:listDivider">@drawable/divider</item>,并在divider.xml中自行绘制矩形。而后两种布局中,默认的分割线是不合适的DividerGridItemDecoration是自定义的。主要判断如果是最后一行,则不需要绘制底部;如果是最后一列,则不需要绘制右边,整个判断也考虑到了StaggeredGridLayoutManager的横向和纵向,所以稍稍有些复杂。有兴趣的可以在源码中自行解读。

    mRcList.setHasFixedSize(true)的作用查了一下,解释如下:

    //setHasFixedSize() is used to let the RecyclerView keep the same size.
    //This information will be used to optimize itself.
    

    最后进行数据初始化以及设置Adapter

    for(int i=0; i<=20 ; i++){
        mData.add("Recycler");
    }
    mAdapter = new RecyclerAdapter(mData);
    mRcList.setAdapter(mAdapter);
    



    从效果图中可以看到,使用RecyclerView实现了两种不同的布局,通过背景颜色进行区分。而且,可以动态的为RecyclerView设置三种不同的布局并且当点击主界面的删除按钮时,实现了删除最后一个Item的操作,这里notifyDataSetChanged()是通知Adapter数据发生了改变

    public void delRecycler(View view) {
            if (mData.size()> 0) {
                mData.remove(mData.size()- 1);
                mAdapter.notifyDataSetChanged();
            }
    }
    

    关于RecyclerView动画效果以及点击事件的设置方法,在Android开发——RecyclerView特性以及基本使用方法(二)中进行介绍。

    源码下载地址点这里

  • 相关阅读:
    实用脚本 2 Linux下定时执行脚本
    SSH原理与运用(一):远程登录
    SSH原理与运用(二):远程操作与端口转发
    注册页面
    注册页面2
    CSS實現網頁漸變背景
    SQL Server Log文件“減肥”方法
    发布一个jquery插件在Web下输入密码时提示大写锁定键
    新增流水号
    ftp图片上传
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461453.html
Copyright © 2011-2022 走看看