Android RecylerView入门教程

 更新时间:2016年07月20日 15:00:11   作者:冥萧阳  
这篇文章主要介绍了Android RecylerView入门教程的相关资料,很适合刚入门的新手学习,非常不错,具有参考借鉴价值,需要的朋友可以参考下

今年Google I/0大会,Google开放了两个全新的视图:RecyclerView和CardView。这篇文章会提供关于RecylerView的简介。
RecylerView作为support-library发布出来,这对开发者来说绝对是个好消息。因为可以在更低的Android版本上使用这个新视图。下面我们看如何获取RecylerView。首先打开Android SDK Manager,然后更新Extras->Android Support Library即可。

然后在本地../sdk/extras/android/support/v7中找到recyclerview。我已经将下载好的Recyclerview整理成一个Eclipse可编译的Library工程上传到Github,有需求的同学请戳链接

示例程序

我将通过RecylerView制作一个横向滑动的“ListView”,下面是示例程序的截图。并在ActionBar上设置数据的添加/删除操作。请同学们注意,RecyclerView的接口Google可能会继续优化和修改,所以最终的版本可能和我提供的程序有出入。Demo程序Github链接

为什么要使用RecyclerView?

Google在是这样描述RecyclerView的:

"A flexible view for providing a limited window into a large data set."
所以RecyclerView适用于无法在一个屏幕范围内展现格式一样的数据时,需要用多行或多列来展示。例如展示联系人,图片,视频等。用户需要滑动屏幕来查看数据,这时RecyclerView的特性就有用武之地了。比如,当用户滑动使当前一个可视的Item滑出屏幕,这个Item的视图将会被回收并在一个新Item进入可视范围后重新被使用。

如下图所示,用户滑动向上滑动左边的RecyclerView,No.0和No.1就会滑出屏幕可视范围,这时右图的No.0和No.1的视图将会被RecyclerView放入一个可重复利用的缓存中以备再次使用。

可回收利用View是个很实用的功能,它不仅可以减少CPU不断inflate View的开销,而且可以节省缓存View的内存开销。
这时,你可能会问:这不是一个新功能啊!是的,我们已经在使用ListView的时候使用了这个机制,但是当使用ListView时,显示,回收等功能是紧密耦合在一起的,Google现在发布RecyclerView,使方法更灵活,开发者也能自定义各种各样的显示效果。

RecyclerView不再负责显示工作

和ListView不一样的是,RecyclerView不再负责Item的摆放等显示方面的功能。所有和布局、绘制等方面的工作Google都其拆分成不同的类进行管理。所以开发者可以自定义各种各样满足定制需求的的功能类。

下面是一些和RecyclerView相关的非常重要的类列表。

ViewHolder

关于ViewHolder,Google早就推荐开发者使用,但也只是建议。但是现在,RecyclerView.Adapter最终要求开发者必须使用ViewHolder。如果你还对ViewHolder不了解,请阅读Android training session

Demo通过继承RecyclerView.ViewHolder来实现自定义:

public class MyViewHolder extends ViewHolder implements OnClickListener,OnLongClickListener{ 
public ImageView iv; 
public TextView tv; 
private MyItemClickListener mListener; 
private MyItemLongClickListener mLongClickListener; 
public MyViewHolder(View rootView,MyItemClickListener listener,MyItemLongClickListener longClickListener) { 
super(rootView); 
iv = (ImageView)rootView.findViewById(R.id.item_iv); 
tv = (TextView)rootView.findViewById(R.id.item_tv); 
this.mListener = listener; 
this.mLongClickListener = longClickListener; 
rootView.setOnClickListener(this); 
rootView.setOnLongClickListener(this); 
} 
/** 
* 点击监听 
*/ 
@Override 
public void onClick(View v) { 
if(mListener != null){ 
mListener.onItemClick(v,getPosition()); 
} 
} 
/** 
* 长按监听 
*/ 
@Override 
public boolean onLongClick(View arg0) { 
if(mLongClickListener != null){ 
mLongClickListener.onItemLongClick(arg0, getPosition()); 
} 
return true; 
} 
} 

RecyclerView.Adapter

Adapter负责扮演两个角色:不仅为底部数据提供支持而且还负责为数据创建合适的视图。Adapter适用在Android很多控件,例如ListView、AutoCompleteTextView等。

继承RecyclerView.Adapter需要实现以下三个方法:

public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType)
public void onBindViewHolder(ViewHolder holder,int position)
public int getItemCount()
Demo中的Adapter:
[java] view plain copy
public class MyAdapter extends Adapter<MyViewHolder> { 
private List<MyItemBean> mData; 
private MyItemClickListener mItemClickListener; 
private MyItemLongClickListener mItemLongClickListener; 
public MyAdapter(List<MyItemBean> data){ 
this.mData = data; 
} 
@Override 
public int getItemCount() { 
return mData.size(); 
} 
@Override 
public void onBindViewHolder(MyViewHolder holder, int position) { 
MyItemBean bean = mData.get(position); 
holder.tv.setText(bean.tv); 
} 
@Override 
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent,false); 
MyViewHolder vh = new MyViewHolder(itemView,mItemClickListener,mItemLongClickListener);
return vh; 
} 
} 

onCreateViewHolder中负责为Item创建视图,onBindViewHolder负责将数据绑定到Item的视图上。

RecyclerView.LayoutManager

LayoutManager是RecyclerView中最有意思的类。该类负责将每个Item视图在RecylerView中的布局。目前Google提供了LayoutManager的一个子类:LinearLayoutManager。LinearLayoutManager提供了横向和竖向两种布局,Demo就是使用LinearLayoutManger的横向布局实现的。

如果要自定义LayoutManager,需要实现一个abstract方法

public LayoutParams generateDefaultLayoutParams()

Demo中为RecylerView添加LinearLayoutManager的片段:

MyLayoutManager manager = new MyLayoutManager(this);
manager.setOrientation(LinearLayout.HORIZONTAL);//默认是LinearLayout.VERTICAL
mRecyclerView.setLayoutManager(manager);

LinearLayoutManager提供了如下几个方法来帮助开发者获取屏幕上的顶部item和底部item:

findFirstVisibleItemPosition()
findFirstCompletelyVisibleItemPosition()
findLastVisibleItemPosition()
findLastCompletelyVisibleItemPosition()

RecyclerView.ItemDecoration

通过ItemDecoration可以使各个Item在视觉上相互分开,其实和ListView的Divider很像。ItemDecoration并不是RecyclerView必须设置的,开发者可以不设置或者设置多个Decoration。RecyclerView会遍历所有的ItemDecoration并调用各自的绘图方法。

继承ItemDecoration需要实现以下三个方法:

public void onDraw(Canvas c,RecyclerView parent,RecyclerView.State state)

public void getItemOffset(Rect outRect,int itemPosition,RecyclerView parent)

LayoutManager会调用getItemOffset方法来计算每个Item的Decoration合适的尺寸。

Demo中自定义了一个ItemDecoration来实现ListView的Divider效果:

public class MyDecoration extends ItemDecoration { 
private static final int[] ATTRS = new int[]{ 
android.R.attr.listDivider 
}; 
private Drawable mDivider; 
public MyDecoration(Context ctx){ 
final TypedArray a = ctx.obtainStyledAttributes(ATTRS); 
mDivider = a.getDrawable(0); 
} 
@Override 
public void onDraw(Canvas c, RecyclerView parent, State state) { 
int top = parent.getPaddingTop(); 
int bottom = parent.getHeight() - parent.getPaddingBottom(); 
int childCount = parent.getChildCount(); 
for(int i=0;i < childCount;i++){ 
View child = parent.getChildAt(i); 
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams)child.getLayoutParams(); 
int left = child.getRight() + layoutParams.rightMargin; 
int right = left + mDivider.getIntrinsicWidth(); 
mDivider.setBounds(left, top, right, bottom); 
mDivider.draw(c); 
} 
} 
@Override 
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, 
State state) { 
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); 
} 
} 

RecyclerView.ItemAnimatior

当Item有以下三种操作时ItemAnimatior会为RecyclerView提供动画效果:

删除某一个Item

添加一个新的Item

移动某个Item

Google提供了一个名为DefaultItemAnimator的默认ItemAnimator供开发者使用。如果开发者不为RecyclerView设置ItemAnimator,RecyclerView也会使用默认的DefaultItemAnimator。
显然,为了让动画效果起效,开发者必须通知Adapter数据有改变。之前我们使用Adapter时会调用notifyDataSetChanged()来通知Adapter数据改变并更新视图,现在RecyclerView,Adapter提供了许多notifyXyz()方法,例如Demo中使用了以下两个方法:
public final void notifyItemInserted(int position)
public final void notifyItemRemoved(int position)

使用RecyclerView

首先,我们先看如何在xml中使用RecyclerView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context="com.xmy.recylerviewdemo.MainActivity" > 
<android.support.v7.widget.RecyclerView 
android:id="@+id/recyclerView" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content"/> 
</RelativeLayout> 

然后需要开发者在代码中实现RecyclerView的组装,大体可概括为以下步骤:

实例化RecyclerView

为RecyclerView设置LayoutManager

为RecyclerView设置Adapater

如果有需求,可以设置一个或多个ItemDecorations,当然,也可以不设置

如果有需求,可以设置ItemAnimator

相关文章

  • Android实现图像切换器

    Android实现图像切换器

    这篇文章主要为大家详细介绍了Android实现图像切换器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • Android自定义ViewGroup实现朋友圈九宫格控件

    Android自定义ViewGroup实现朋友圈九宫格控件

    在我们的实际应用中,经常需要用到自定义控件,比如自定义圆形头像,自定义计步器等等,这篇文章主要给大家介绍了关于Android自定义ViewGroup实现朋友圈九宫格控件的相关资料,需要的朋友可以参考下
    2021-07-07
  • Flutter中渐变色的使用案例分享

    Flutter中渐变色的使用案例分享

    在日常的开发中,UI为了让界面更加吸引人往往会在界面上用到大量的渐变色,本文将通过几个案例更好的去了解Flutter中渐变色的使用,需要的可以参考一下
    2023-06-06
  • Android路由框架Router分析详解

    Android路由框架Router分析详解

    本篇文章主要介绍了Android路由框架Router分析详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Android Listview点赞问题关于图片重复问题

    Android Listview点赞问题关于图片重复问题

    最近在开发android方面的项目时,遇到很多问题,下面小编以listview 与 baseadapter结合使用为例,给大家分享下关于点赞的的时候 图片重复问题的解决方法,一起看看吧
    2016-11-11
  • Android中创建快捷方式及删除快捷方式实现方法

    Android中创建快捷方式及删除快捷方式实现方法

    这篇文章主要介绍了Android中创建快捷方式及删除快捷方式实现方法,本文直接给出实现代码,需要的朋友可以参考下
    2015-06-06
  • 深入剖析Android系统中Service和IntentService的区别

    深入剖析Android系统中Service和IntentService的区别

    这篇文章主要介绍了Android系统中Service和IntentService的区别,与普通的服务相比,IntentService可以开启单独的线程来处理intent请求,需要的朋友可以参考下
    2016-04-04
  • Android 2.3 拨号上网流程从源码角度进行分析

    Android 2.3 拨号上网流程从源码角度进行分析

    SIM卡实现拨号上网功能之前需要设置一番,这些设置步骤究竟做了哪些事情呢?我们现在就从源码的角度进行分析
    2013-01-01
  • Android NDK开发(C语言字符串)

    Android NDK开发(C语言字符串)

    这篇文章主要介绍了Android NDK开发 C语言字符串 ,主要以字符数组、字符指针及一些字符串常用的方法的方法未来全文展开内容,需要的朋友可以参考一下
    2021-12-12
  • Android RIL使用详解

    Android RIL使用详解

    这篇文章主要介绍了Android RIL使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论