前言

RecyclerView已经出来好一段时间了,对于新接触Android的学员来说大多数使用的是ListViewGridView,对于RecyclerView的使用可能都不是很熟悉,相信这片文章能很好的带你进去RecyclerView的大门,快速了解与掌握新技术。

添加依赖

大家使用ListViewGridView只要在xml中引用就可以了,没错RecyclerView也是一样,但在引用前要先添加依赖,在项目的app目录下的build.gradl的dependencies中添加:

compile 'com.android.support:recyclerview-v7:23.2.0'
完了之后别忘了Sync Now

Adapter变化

既然要有ListViewGridView的效果自然不能少了adapter,而RecyclerViewadapter主要有两个重大的变化,原来adapter中的getView()方法取消了,替换成了onCreateViewHolder()onBindViewHolder()。其实就是分成了两部分,一部分创建视图另一部分绑定数据,是不是感觉层次更清晰了呢,下面主要介绍之两大方法的使用。

onCreateViewHolder

说白了这个方法就是创建视图,在创建之前要创建个ViewHolder相信在原来的adapter中应该有使用过吧.这里继承RecyclerView.ViewHolder

public static class NormalViewHolder extends RecyclerView.ViewHolder {
        @Bind(R.id.item_tv)
        TextView itemTv;
        public NormalViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }   

然后在onCreateViewHolder中调用:

    @Override
    public NormalViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new NormalViewHolder(mLayoutInflater.inflate(R.layout.item_text, parent, false));
    }
    

onBindViewHolder

视图创建完毕就是简单的绑定了,使用holder对控件进行绑定设置数据:

    @Override
    public void onBindViewHolder(NormalViewHolder holder, int position) {
        holder.itemTv.setText((CharSequence) mListData.get(position));
    }

OK了,是不是感觉很简单呢?是的就是这么简单,至于设置adapter就不说了相信之后的步骤大家都会了。

setLayoutManager

你是不是想说如何设置显示的方式是ListViewGridView,这个其实更加简单只需一句代码,setLayoutManager()即可:

switch (type) {
            case App.LINEAR_LAYOUT:
                //ListView
                recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
                break;
            case App.GRID_LAYOUT:
                //GridView
                gridLayoutManager = new GridLayoutManager(getActivity(),3);
                recyclerView.setLayoutManager(gridLayoutManager);
                break;                
            case App.STAGGERED_GRID_LAYOUT:
                //Can customize the waterfall flow
                recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL));
                break;
            default:
                break;
        }
设置了显示的方式后再setAdapter()即可,效果图还是放到最后一起显示吧

ListView与GridView嵌套效果

如果要实现首尾是ListView布局效果,中间的GridView效果,我们可以使用RecyclerView.Adapter提供的getItemViewType(int position)方法,注意这里与ListViewadapter不同只有这一个方法,没有getViewTypeCount() 方法,我们可以通过首尾要显示的行数来控制显示的布局

@Override
    public int getItemViewType(int position) {
        mHeadCount = getHeadCount();
        mContentCount = getContentCount();
        mBottomCount = mHeadCount + mContentCount;
        if (mHeadCount > position) {
            return App.LINEAR_LAYOUT;//ListView
        } else if (mBottomCount <= position) {
            return App.STAGGERED_GRID_LAYOUT;//Can customize the waterfall flow
        } else {
            return App.GRID_LAYOUT;//GridView
        }
    }
根据不同的viewtype返回不同的布局
@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case App.LINEAR_LAYOUT:
                return onCreateHeadViewHolder(parent);
            case App.GRID_LAYOUT:
                return onCreateContentViewHolder(parent);
            case App.STAGGERED_GRID_LAYOUT:
                return onCreateBottomViewHolder(parent);
            default:
                return null;
        }
    }

RecyclerView动画

RecyclerViewadapter提供了一些简单的动画实现,下面是一部分:

  • notifyItemRemoved(int position)
  • notifyItemInserted(int position)
  • notifyItemChanged(int position)
  • notifyItemRangeChanged(int positionStart,int itemCount)

只要在数据改变时通过adapter调用就行:

 @OnClick(R.id.item_tv)
        public void onClick() {
            if (getLayoutPosition() != 1) {
                animationAdapter.mListData.add("add"+getLayoutPosition());
                animationAdapter.notifyItemInserted(getLayoutPosition());
            } else {
                animationAdapter.mListData.remove(getLayoutPosition());
                animationAdapter.notifyItemRemoved(getLayoutPosition());
            }
        }

使用recyclerViewsetItemAnimator()可以设置动画:

recyclerView.setItemAnimator(new DefaultItemAnimator());

当然你也可以实现自己的动画,只要extends ItemAnimator重写几个方法,这里就不展开了,读者可以自己去试试。

RecyclerView的CursorAdapter

讲到这里了你可以能会认为CursorAdapter也是跟原来的差不多,但我要说的是RecyclerView并没有提供有关与CursorAdapter的操作。所以当我们要使用CursorAdapter时要怎么办呢?我们只能自己实现一个CursorAdapter的抽象类,是不是感觉头痛,这一点看起来确实有点麻烦,但是我告诉你们实现也是很简单的一件事,为什么这么说呢,因为我们只要仿造ListViewCursorAdapter就可以了。

CursorFilter

这个是Cursor的过滤器,我们无需做什么,找到ListViewCursorFilter复制就可以了。代码没什么贴的,都是源码,自己可以去查看.

RecyclerBaseCursorAdapter

这个抽象类大部分都是与ListViewCursorAdapter相同,只是有几个地方需要特别提醒下

  • 原来的有notifyDataSetInvalidated()方法,但RecyclerView没有提供该方法,我们可以使用notifyDataSetChanged()替代
  • 原来的hasStableIds() 方法也没用,我们也可以使用setHasStableIds(true)设置为ture来实现相同的效果
  • 原来的getView()方法要替换成onBindViewHolder()方法
void init(Context context, Cursor c, int flags) {
        boolean cursorPresent = c != null;
        mCursor = c;
        mDataValid = cursorPresent;
        mContext = context;
        mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
        if ((flags & FLAG_REGISTER_CONTENT_OBSERVER) == FLAG_REGISTER_CONTENT_OBSERVER) {
            mChangeObserver = new ChangeObserver();
            mDataSetObserver = new MyDataSetObserver();
        } else {
            mChangeObserver = null;
            mDataSetObserver = null;
        }

        if (cursorPresent) {
            if (mChangeObserver != null) c.registerContentObserver(mChangeObserver);
            if (mDataSetObserver != null) c.registerDataSetObserver(mDataSetObserver);
        }
        //should set true to init
        setHasStableIds(true);
    }
@Override
        public void onInvalidated() {
            mDataValid = false;
//            notifyDataSetInvalidated();
            //there is no notifyDataSetInvalidated method we should use notifyDataSetChanged method;
            notifyDataSetChanged();
        }
基本上主要的就是这些了,更多详情可以查看后面的Demo链接,最后使用都相同的套路,继承该抽象类,相信应该没有问题。

效果图

RecyclerView.gif

结语

最后感谢大家的阅读,有不足的地方欢迎指出。

源码地址链接:https://github.com/idisfkj/Re...
博客文章链接:https://idisfkj.github.io/201...

关注

clipboard.png


午后一小憩
2.9k 声望838 粉丝