Recyclerview的用法
前言
简单的介绍下Recyclerview的用法
内容
Android5.0 RecyclerView特点、用法、及自定义动画
RecyclerView派生于ViewGroup,是一种更先进的柔性版的ListView。这个小工具是一个容器,用于显示,它能非常有效地维护了数量有限而滚动大的数据集。相对于ListView来说RecyclerView使用起来更加灵活但同时也增加了一定的复杂度,它在最新的support-V7版本中提供支持.本文主要分为以下2个部分:
- RecyclerView的简单使用
- 简单介绍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);
// 设置布局管理器   
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.addItemDecoration(new Decoration(this));
Demo中实现的效果如下:
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的使用可以实现不错的视觉效果,下面为默认模式和加入简单划线对比:
LayoutManager
这个类决定视图被放在画面中哪个位置,但这只是它的众多职责之一。它可以管理滚动和循环利用,ListView则不能设置为横向。在最新的support v7 中LayoutManager有三个实现类,LinearlayoutManager,GridLayoutManager和StaggeredGridLayoutManager,LayoutManager可以模拟列表的视图,但是没有页眉和页尾。开发者可以仿照原生给出的LinearLayoutManager代码创建一个BaseLayoutManager,并且基于此进行扩展。而在Android L以前,为了给LIstView后期进行扩展,ListVIew的主体功能实现都放在AbsListView,然后通过ListView,和GridVIew实现不同的布局,而在RecyclerVIew中则可以通过设置不同的LayoutManager达到此效果。下面给出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);
上一篇: TCP三次握手和四次挥手的详解