欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Recyclerview的用法

程序员文章站 2022-06-14 11:18:01
...

前言


简单的介绍下Recyclerview的用法

内容


Android5.0 RecyclerView特点、用法、及自定义动画

   RecyclerView派生于ViewGroup,是一种更先进的柔性版的ListView。这个小工具是一个容器,用于显示,它能非常有效地维护了数量有限而滚动大的数据集。相对于ListView来说RecyclerView使用起来更加灵活但同时也增加了一定的复杂度,它在最新的support-V7版本中提供支持.本文主要分为以下2个部分:

  1. RecyclerView的简单使用
  2. 简单介绍RecyclerView的四大组件

RecyclerView的简单使用

   虽说相对于以前的ListView,RecyclerView基本上没有新增的功能,但在功能的具体实现和使用的方法上两者却有着很大的区别。要使用RecyclerView,需要先了解这几个个元素:LayoutManager,RecyclerView.Adapter,Itemanimator以及itemDecoration。LayoutManager控制RecyclerView的布局以及资源的回收,RecyclerView.Adapter用于设置数据,ItemAnimator用于创建列表的Item动画,而ItemDecoration则用于绘制列表子项额外的内容。以上四个均为RecyclerView中的抽象类,带有最基本的接口和参数,开发者可以通过继承以上几个类进行扩展实现不同的功能效果。下面首先通过附件中的SimpleDemo介绍一下RecyclerVIew的使用方法:

1. 定义布局文件

   activity_main.xml的主要布局如下:

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />

   RecyclerView是android.support.v7包下提供的控件,要使用RecyclerView可以直接把源码上整个的v7包导入到工程中, 或者把当前的API升级到21,在sdk/extras/android/support/v7目录下找到android-support-v7-recyclerview.jar(其实也可以直接从网上的Demo中直接copy对应的jar包过去,不过应当注意最近的版本中部分接口已经做了相应的变化 ,应下载最新的jar包),将其导入到工程内即可。

2. 设置RecyclerView.Adapter

   Demo中的SimpleAdapter.java中的主要代码如下:

//定义ViewHolder,包含两个控件
public static class ViewHolder extends RecyclerView.ViewHolder{

    public TextView mTextView;
    public ImageView mImageView;

    public ViewHolder(View itemView) {
        super(itemView);
    }
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = View.inflate(viewGroup.getContext(), R.layout.item_layout, null);
    // 创建ViewHolder
    ViewHolder holder = new ViewHolder(view);
    holder.mImageView = (ImageView)view.findViewById(R.id.id_index_item_image);
    holder.mTextView = (TextView)view.findViewById(R.id.id_index_item_text);
    return holder;
}

@Override
public void onBindViewHolder(ViewHolder viewHolder,int i) {
    //设置TextView内容
    viewHolder.mTextView.setText(mData[i]);
    //设置ImageView资源
    viewHolder.mImageView.setImageResource(R.drawable.mail);        
}

3. 定义Decoration

   Decoration.java的主要代码如下:

@Override
public void onDrawOver(Canvas c, RecyclerView parent) {
    if (mDivider == null) {
        super.onDrawOver(c, parent);
        return;
    }
    //为横向布局的RecyclerView的每个Item设置下划线
    if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
        final int childCount = parent.getChildCount();

        for (int i = 1; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int size = mDivider.getIntrinsicHeight();
            final int top = child.getTop() - params.topMargin;
            final int bottom = top + size;
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }

4. 初始化操作

   在MainActivity.java的主要代码如下:

mRecyclerView = (RecyclerView)findViewById(R.id.recyclerview_vertical);
SimpleAdapter simpleAdapter = new SimpleAdapter(dataset, this);
mRecyclerView.setAdapter(simpleAdapter);
// 创建一个线性布局管理器
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// 设置布局管理器&#160;&#160;&#160;
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.addItemDecoration(new Decoration(this));

   Demo中实现的效果如下:

Recyclerview的用法

RecyclerView的四大组件

Adapter

   RecyclerView使用的Adapter与ListView使用的BaseAdapter类似,但是,前者定义的Adapter必须继承自RecyclerView.Adapter,内部必须重写三个方法,oncreateViewHolder()onbindViewHolder()getItemCount(),onCreateViewHolder()类似于BaseAdapter中的getview(),ListView可以选择使用ViewHolder()但RecyclerView为了回收资源,必须使用ViewHolder。先对比两者子类部分代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    //如果缓存convertView为空,则需要创建View
    if(convertView == null)
    {
        holder = new ViewHolder();
        //根据自定义的Item布局加载布局
        convertView = mInflater.inflate(R.layout.list_item, null);
        holder.img = (ImageViewShadow)convertView.findViewById(R.id.img);
        holder.title = (TextView)convertView.findViewById(R.id.tv);
        holder.info = (TextView)convertView.findViewById(R.id.info);
        //将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag
        convertView.setTag(holder);
    }else
    {
        holder = (ViewHolder)convertView.getTag();
    }

    Drawable D = StrokeDrawableUtils.createStrokeDrawable(getResources().getDrawable(R.drawable.mail), getResources());
    holder.img.setImageDrawable(D);
    ho.setText((String)data.get(position).get("title"));
    holder.info.setText((String)data.get(position).get("info"));

    return convertView;
}    

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = mInflater.inflate(R.layout.activity_index_item,
            viewGroup, false);
    //创建viewHolder对象和绑定viewHolder內的所有组件
    ViewHolder viewHolder = new ViewHolder(view);

    viewHolder.mImg = (ImageView) view
            .findViewById(R.id.id_index_gallery_item_image);
    viewHolder.mTxt = (TextView)view.findViewById(R.id.id_index_gallery_item_text);
    return viewHolder;
}

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int i) {
    viewHolder.mImg.setImageResource(mDatas.get(i));
    viewHolder.mTxt.setText(String.valueOf(i));
    ....

}

   对比以上代码,可以看出在RecyclerView中, ViewHolder直接充当缓存的单位,然后convertView作为ViewHolder的成员变量保持在ViewHolder中,也就是说,假设没有屏幕显示10个条目,则会创建10个ViewHolder缓存起来,每次复用的是ViewHolder,所以他把getView这个方法变为了onCreateViewHolder,而ListView的复用机制则是利用静态的holder把conertiew里面包含的所有组件保存起来,并通过setTag将其与conertView捆绑在一起,convertView是复用对象。

ItemDecoration

   Decoration意为修饰,android的开发文档中有这样的说明:ItemDecoration允许程序添加自定义的绘画或者布局边距,常用于分割列表子项,突显视觉上的界限。这类似于listView中的devider,但listView中所画的分割线是在Listview内部实现,对于开发者来说,灵活性较低。在新的RecyclerView中很好的解决这个问题,RecycView把对Decoration的控制交给了开发者,RecyclerView默认不带Decoration,但继承自RecyclerView.ItemDecoration开发者通过重写public void onDrawOver(Canvas c, RecyclerView parent)和public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent)等,结合CardView的使用可以实现不错的视觉效果,下面为默认模式和加入简单划线对比:

Recyclerview的用法
Recyclerview的用法

LayoutManager

   这个类决定视图被放在画面中哪个位置,但这只是它的众多职责之一。它可以管理滚动和循环利用,ListView则不能设置为横向。在最新的support v7 中LayoutManager有三个实现类,LinearlayoutManager,GridLayoutManager和StaggeredGridLayoutManager,LayoutManager可以模拟列表的视图,但是没有页眉和页尾。开发者可以仿照原生给出的LinearLayoutManager代码创建一个BaseLayoutManager,并且基于此进行扩展。而在Android L以前,为了给LIstView后期进行扩展,ListVIew的主体功能实现都放在AbsListView,然后通过ListView,和GridVIew实现不同的布局,而在RecyclerVIew中则可以通过设置不同的LayoutManager达到此效果。下面给出RecyclerVIew不同的布局效果:

Recyclerview的用法
Recyclerview的用法
Recyclerview的用法

   另外需要说明一下,使用RecylerView时必须加入LayoutManager,否则会出现报错。

ItemAnimator

   在ListView中我们通常在Adatper 的getview()的时候对特定的item做动画。在RecyclerView中加入了新的实现方法。ItemAnimator同样是RecyclerView中的的抽象类,在V7包中给出了默认的实现类DefaultItemAnimator(渐隐),开发者同样的可以通过继承RecyclerView.ItemAnimator,参考DefaultAnimator建立BaseItemAnimator,然后对其进行扩展打造不同的动画效果,使用时通过调用Recycler.Adapter中的notifyItemChanged()notifyItemInserted()等方法触发,如果是使用默认的动画效果,直接添加如下代码即可。

final DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
recyclerView.setItemAnimator(defaultItemAnimator);

Recyclerview的用法