首页 > 代码库 > RecyclerView 介绍 基本使用

RecyclerView 介绍 基本使用

介绍

文档位置:https://developer.android.google.cn/reference/android/support/v7/widget/RecyclerView.html
A flexible view for providing a limited window into a large data set.

RecylerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字recylerview即回收view也可以看出。从它类名上看,RecyclerView代表的意义是,我只管Recycler View,也就是说RecyclerView只管回收与复用View,其他的你可以自己去设置。可以看出其高度的解耦,给予你充分的定制自由(所以你才可以轻松的通过这个控件实现ListView,GirdView,瀑布流等效果)。

看到这也许有人会问,不是已经有ListView了吗,为什么还要RecylerView呢?

根据官方的介绍,RecylerView是ListView的升级版,既然如此那RecylerView必然有它的优点:
  • RecylerView封装了ViewHolder的回收复用,也就是说RecylerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。
  • 提供了一种插拔式的体验,高度的解耦,异常的灵活。针对一个Item的显示RecylerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还有StaggeredGridLayoutManager等),也就是说RecylerView不再拘泥于ListView的线性展示方式,它也可以实现GridView等多种效果。你想控制Item的分隔线,可以通过继承RecylerView的ItemDecoration这个类,然后针对自己的业务需求去书写代码。
  • 可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecylerView有其自己默认的实现。

基本使用

添加依赖【compile ‘com.android.support:appcompat-v7:25.3.1‘】
TMD添加后竟然找不到RecyclerView,因为你还要再添加【compile ‘com.android.support:recyclerview-v7:25.3.1‘】
  1. <android.support.v7.widget.RecyclerView
  2. android:id="@+id/rv"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content"/>
代码
  1. android.support.v7.widget.RecyclerView
  2. public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild
  • 设置适配器,setAdapter(Adapter)
  • LayoutManager控制显示的方式,setLayoutManager(RecyclerView.LayoutManager)
  • ItemDecoration控制Item间的间隔(可绘制),addItemDecoration(RecyclerView.ItemDecoration)
  • ItemAnimator控制Item增删的动画,setItemAnimator(RecyclerView.ItemAnimator)
  • 点击、长按事件,要自己写

Glossary 使用到的术语

  • Adapter: A subclass of RecyclerView.Adapter responsible职责为 for providing views that represent表示 items in a data set.
  • Position: The position of a data item within an Adapter.
  • Index: The index of an attached child view as used in a call to getChildAt(int). Contrast with与...相比/不同 Position.
  • Binding: The process of preparing a child view to display data corresponding to与...一致 a position within the adapter.
  • Recycle (view): A view previously之前 used to display data for a specific adapter position may be placed in a cache for later之后 reuse to display the same type of data again later. This can drastically improve performance by skipping跳过 initial初始化 layout inflation填充 or construction构造.
  • Scrap废弃 (view): A child view that has entered into a temporarily临时的 detached state during layout. Scrap views may be reused without becoming fully detached from the parent RecyclerView, either unmodified if no rebinding is required or modified by the adapter if the view was considered dirty.
  • Dirty脏数据 (view): A child view that must be rebound by the adapter before being displayed.

RecyclerView中的 Position

1、官方文档
RecyclerView introduces引入 an additional额外 level of abstraction抽象 between the RecyclerView.Adapter and RecyclerView.LayoutManager to be able to detect发现 data set changes in batches during a layout calculation. This saves LayoutManager from tracking adapter changes to calculate animations. It also helps with performance because all view bindings happen at the same time and unnecessary bindings are avoided.

For this reason, there are two types of position related methods in RecyclerView:
  • layout position: Position of an item in the latest layout calculation. This is the position from the LayoutManager‘s perspective.
  • adapter position: Position of an item in the adapter. This is the position from the Adapter‘s perspective.
These two positions are the same except the time between dispatching adapter.notify* events and calculating the updated最新的 layout.

Methods that return or receive *LayoutPosition* use position as of the latest layout calculation (e.g. getLayoutPosition(), findViewHolderForLayoutPosition(int)). These positions include all changes until the last layout calculation. You can rely on these positions to be consistent with what user is currently seeing on the screen. For example, if you have a list of items on the screen and user asks for the 5th element, you should use these methods as they‘ll match what user is seeing.

The other set of position related methods are in the form of *AdapterPosition*. (e.g. getAdapterPosition(), findViewHolderForAdapterPosition(int)) You should use these methods when you need to work with up-to-date最近的 adapter positions even if they may not have been reflected to layout yet. For example, if you want to access使用 the item in the adapter on a ViewHolder click, you should use getAdapterPosition(). Beware当心 that these methods may not be able to calculate adapter positions if notifyDataSetChanged() has been called and new layout has not yet been calculated. For this reasons, you should carefully handle NO_POSITION or null results from these methods.

When writing a RecyclerView.LayoutManager you almost always want to use layout positions whereas反之 when writing an RecyclerView.Adapter, you probably want to use adapter positions.

2、stackoverflow中的解释
参考:http://stackoverflow.com/questions/29684154/recyclerview-viewholder-getlayoutposition-vs-getadapterposition 

This is a tricky situation, sorry that docs are not sufficient充足的.

When adapter contents change (and you call notify***()) RecyclerView requests a new layout. From that moment, until layout system decides to calculate a new layout (<16 ms), the layout position and adapter position may not match because layout has not reflected adapter changes yet.

In your use case, since your data is related to your adapter contents (and I assume that data is changed at the same time with adapter changes), you should be using adapterPosition.

Be careful though, if you are calling notifyDataSetChanged(), because it invalidates everything, RecyclerView does not know that ViewHolder‘s adapter position until next layout is calculated. In that case, getAdapterPosition() will return RecyclerView#NO_POSITION (-1).

But lets say if you‘ve called notifyItemInserted(0), the getAdapterPosition() of ViewHolder which was previously at position 0 will start returning 1 immediately. So as long as you are dispatching granular颗粒状的 notify events, you are always in good state (we know adapter position even though new layout is not calculated yet).

Another example, if you are doing something on user click, if getAdapterPosition() returns NO_POSITION, it is best to ignore that click because you don‘t know what user clicked (unless you have some other mechanism, e.g. stable ids to lookup the item).

API

  • void  addFocusables(ArrayList<View> views, int direction, int focusableMode)  介绍:Adds any focusable views that are descendants of this view (possibly including this view if it is focusable itself) to views.
  • void  addItemDecoration(RecyclerView.ItemDecoration decor)  介绍:Add an RecyclerView.ItemDecoration to this RecyclerView.
  • void  addItemDecoration(RecyclerView.ItemDecoration decor, int index)  介绍:Add an RecyclerView.ItemDecoration to this RecyclerView.
  • void  addOnChildAttachStateChangeListener(RecyclerView.OnChildAttachStateChangeListener listener)  介绍:Register a listener that will be notified whenever a child view is attached to or detached from RecyclerView.
  • void  addOnItemTouchListener(RecyclerView.OnItemTouchListener listener)  介绍:Add an RecyclerView.OnItemTouchListener to intercept touch events before they are dispatched to child views or this view‘s standard scrolling behavior.
  • void  addOnScrollListener(RecyclerView.OnScrollListener listener)  介绍:Add a listener that will be notified of any changes in scroll state or position.
  • void  clearOnChildAttachStateChangeListeners()  介绍:Removes all listeners that were added via addOnChildAttachStateChangeListener(OnChildAttachStateChangeListener).
  • void  clearOnScrollListeners()  介绍:Remove all secondary listener that were notified of any changes in scroll state or position.
  • int  computeHorizontalScrollExtent()  介绍:Compute the horizontal extent长度 of the horizontal scrollbar‘s thumb within the horizontal range.
  • int  computeHorizontalScrollOffset()  介绍:Compute the horizontal offset of the horizontal scrollbar‘s thumb within the horizontal range.
  • int  computeHorizontalScrollRange()  介绍:Compute the horizontal range that the horizontal scrollbar represents.
  • int  computeVerticalScrollExtent()  介绍:Compute the vertical extent of the vertical scrollbar‘s thumb within the vertical range.
  • int  computeVerticalScrollOffset()  介绍:Compute the vertical offset of the vertical scrollbar‘s thumb within the vertical range.
  • int  computeVerticalScrollRange()  介绍:Compute the vertical range that the vertical scrollbar represents.
  • boolean  dispatchNestedFling(float velocityX, float velocityY, boolean consumed)  介绍:Dispatch a fling to a nested scrolling parent.
  • boolean  dispatchNestedPreFling(float velocityX, float velocityY)  介绍:Dispatch a fling to a nested scrolling parent before it is processed by this view.
  • boolean  dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow)  介绍:Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
  • boolean  dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow)  介绍:Dispatch one step of a nested scroll in progress.
  • void  draw(Canvas c)  介绍:Manually render this view (and all of its children) to the given Canvas.
  • boolean  drawChild(Canvas canvas, View child, long drawingTime)  介绍:Draw one child of this View Group.
  • View  findChildViewUnder(float x, float y)  介绍:Find the topmost最上面 view under the given point.
  • View  findContainingItemView(View view)  介绍:Traverses横跨、穿越 the ancestors祖先 of the given view and returns the item view that contains it and also a direct child of the RecyclerView.
  • RecyclerView.ViewHolder  findContainingViewHolder(View view)  介绍:Returns the ViewHolder that contains the given view.
  • RecyclerView.ViewHolder  findViewHolderForAdapterPosition(int position)  介绍:Return the ViewHolder for the item in the given position of the data set.
  • RecyclerView.ViewHolder  findViewHolderForItemId(long id)  介绍:Return the ViewHolder for the item with the given id.
  • RecyclerView.ViewHolder  findViewHolderForLayoutPosition(int position)  介绍:Return the ViewHolder for the item in the given position of the data set as of the latest layout pass.
  • RecyclerView.ViewHolder  findViewHolderForPosition(int position)  介绍:This method was deprecated in API level 22.0.0. use findViewHolderForLayoutPosition(int) or findViewHolderForAdapterPosition(int) 
  • boolean  fling(int velocityX, int velocityY)  介绍:Begin a standard标准的 fling with an initial velocity along each axis in pixels per second.
  • View  focusSearch(View focused, int direction)  介绍:Since RecyclerView is a collection ViewGroup that includes virtual children (items that are in the Adapter but not visible in the UI), it employs a more involved focus search strategy that differs from other ViewGroups.
  • ViewGroup.LayoutParams  generateLayoutParams(AttributeSet attrs)  介绍:Returns a new set of layout parameters based on the supplied attributes set.
  • Adapter  getAdapter()  介绍:Retrieves取回 the previously set adapter or null if no adapter is set.
  • int  getBaseline()  介绍:Return the offset of the RecyclerView‘s text baseline from the its top boundary.
  • int  getChildAdapterPosition(View child)  介绍:Return the adapter position that the given child view corresponds to.
  • long  getChildItemId(View child)  介绍:Return the stable item id that the given child view corresponds to.
  • int  getChildLayoutPosition(View child)  介绍:Return the adapter position of the given child view as of the latest completed layout pass.
  • int  getChildPosition(View child)  介绍:This method was deprecated in API level 22.0.0. use getChildAdapterPosition(View) or getChildLayoutPosition(View).
  • RecyclerView.ViewHolder  getChildViewHolder(View child)  介绍:Retrieve the RecyclerView.ViewHolder for the given child view.
  • boolean  getClipToPadding()  介绍:Returns whether this RecyclerView will clip裁剪 its children to its padding, and resize (but not clip) any EdgeEffect边缘效果 to the padded region, if padding is present.
  • RecyclerViewAccessibilityDelegate  getCompatAccessibilityDelegate()  介绍:Returns the accessibility delegate compatibility implementation used by the RecyclerView.
  • void  getDecoratedBoundsWithMargins(View view, Rect outBounds)  介绍:Returns the bounds of the view including its decoration and margins.
  • RecyclerView.ItemAnimator  getItemAnimator()  介绍:Gets the current ItemAnimator for this RecyclerView.
  • RecyclerView.ItemDecoration  getItemDecorationAt(int index)  介绍:Returns an RecyclerView.ItemDecoration previously added to this RecyclerView.
  • RecyclerView.LayoutManager  getLayoutManager()  介绍:Return the RecyclerView.LayoutManager currently responsible for layout policy for this RecyclerView.
  • int  getMaxFlingVelocity()  介绍:Returns the maximum fling velocity used by this RecyclerView.
  • int  getMinFlingVelocity()  介绍:Returns the minimum velocity to start a fling.
  • RecyclerView.OnFlingListener  getOnFlingListener()  介绍:Get the current RecyclerView.OnFlingListener from this RecyclerView.
  • boolean  getPreserveFocusAfterLayout()  介绍:Returns true if the RecyclerView should attempt to preserve currently focused Adapter Item‘s focus even if the View representing the Item is replaced during a layout calculation.
  • RecyclerView.RecycledViewPool  getRecycledViewPool()  介绍:Retrieve this RecyclerView‘s RecyclerView.RecycledViewPool.
  • int  getScrollState()  介绍:Return the current scrolling state of the RecyclerView.
  • boolean  hasFixedSize()  
  • boolean  hasNestedScrollingParent()  介绍:Returns true if this view has a nested scrolling parent.
  • boolean  hasPendingAdapterUpdates()  介绍:Returns whether there are pending adapter updates which are not yet applied to the layout.
  • void  invalidateItemDecorations()  介绍:Invalidates无效 all ItemDecorations.
  • boolean  isAnimating()  介绍:Returns true if RecyclerView is currently running some animations.
  • boolean  isAttachedToWindow()  介绍:Returns true if RecyclerView is attached to window.
  • boolean  isComputingLayout()  介绍:Returns whether RecyclerView is currently computing a layout.
  • boolean  isLayoutFrozen()  介绍:Returns true if layout and scroll are frozen.
  • boolean  isNestedScrollingEnabled()  介绍:Returns true if nested scrolling is enabled for this view.
  • void  offsetChildrenHorizontal(int dx)  介绍:Offset the bounds of all child views by dx pixels.
  • void  offsetChildrenVertical(int dy)  介绍:Offset the bounds of all child views by dy pixels.
  • void  onChildAttachedToWindow(View child)  介绍:Called when an item view is attached to this RecyclerView.
  • void  onChildDetachedFromWindow(View child)  介绍:Called when an item view is detached from this RecyclerView.
  • void  onDraw(Canvas c)  介绍:Implement this to do your drawing.
  • boolean  onGenericMotionEvent(MotionEvent event)  介绍:Implement this method to handle generic motion events.
  • boolean  onInterceptTouchEvent(MotionEvent e)  介绍:Implement this method to intercept all touch screen motion events.
  • void  onScrollStateChanged(int state)  介绍:Called when the scroll state of this RecyclerView changes.
  • void  onScrolled(int dx, int dy)  介绍:Called when the scroll position of this RecyclerView changes.
  • boolean  onTouchEvent(MotionEvent e)  介绍:Implement this method to handle touch screen motion events.
  • void  removeItemDecoration(RecyclerView.ItemDecoration decor)  介绍:Remove an RecyclerView.ItemDecoration from this RecyclerView.
  • void  removeOnChildAttachStateChangeListener(RecyclerView.OnChildAttachStateChangeListener listener)  介绍:Removes the provided listener from child attached state listeners list.
  • void  removeOnItemTouchListener(RecyclerView.OnItemTouchListener listener)  介绍:Remove an RecyclerView.OnItemTouchListener.
  • void  removeOnScrollListener(RecyclerView.OnScrollListener listener)  介绍:Remove a listener that was notified of any changes in scroll state or position.
  • void  requestChildFocus(View child, View focused)  介绍:Called when a child of this parent wants focus
  • boolean  requestChildRectangleOnScreen(View child, Rect rect, boolean immediate)  介绍:Called when a child of this group wants a particular特别的 rectangle to be positioned onto the screen.
  • void  requestDisallowInterceptTouchEvent(boolean disallowIntercept)  介绍:Called when a child does not want this parent and its ancestors to intercept touch events with onInterceptTouchEvent(MotionEvent).
  • void  requestLayout()  介绍:Call this when something has changed which has invalidated the layout of this view.
  • void  scrollBy(int x, int y)  介绍:Move the scrolled position of your view.
  • void  scrollTo(int x, int y)  介绍:Set the scrolled position of your view.
  • void  scrollToPosition(int position)  介绍:Convenience method to scroll to a certain position.
  • void  sendAccessibilityEventUnchecked(AccessibilityEvent event)  介绍:This method behaves exactly as sendAccessibilityEvent(int) but takes as an argument an empty AccessibilityEvent and does not perform a check whether accessibility is enabled.
  • void  setAccessibilityDelegateCompat(RecyclerViewAccessibilityDelegate accessibilityDelegate)  介绍:Sets the accessibility delegate compatibility implementation used by RecyclerView.
  • void  setAdapter(Adapter adapter)  介绍:Set a new adapter to provide child views on demand.
  • void  setChildDrawingOrderCallback(RecyclerView.ChildDrawingOrderCallback childDrawingOrderCallback)  介绍:Sets the RecyclerView.ChildDrawingOrderCallback to be used for drawing children.
  • void  setClipToPadding(boolean clipToPadding)  介绍:Sets whether this ViewGroup will clip its children to its padding and resize (but not clip) any EdgeEffect to the padded region, if padding is present.
  • void  setHasFixedSize(boolean hasFixedSize)  介绍:RecyclerView can perform several optimizations优化 if it can know in advance that RecyclerView‘s size is not affected by the adapter contents.
  • void  setItemAnimator(RecyclerView.ItemAnimator animator)  介绍:Sets the RecyclerView.ItemAnimator that will handle animations involving changes to the items in this RecyclerView.
  • void  setItemViewCacheSize(int size)  介绍:Set the number of offscreen屏幕以外的 views to retain保留 before adding them to the potentially可能的 shared recycled view pool.
  • void  setLayoutFrozen(boolean frozen)  介绍:Enable or disable layout and scroll.
  • void  setLayoutManager(RecyclerView.LayoutManager layout)  介绍:Set the RecyclerView.LayoutManager that this RecyclerView will use.
  • void  setNestedScrollingEnabled(boolean enabled)  介绍:Enable or disable nested scrolling for this view.
  • void  setOnFlingListener(RecyclerView.OnFlingListener onFlingListener)  介绍:Set a RecyclerView.OnFlingListener for this RecyclerView.
  • void  setOnScrollListener(RecyclerView.OnScrollListener listener)  介绍:This method was deprecated in API level 22.1.0. Use addOnScrollListener(OnScrollListener) and removeOnScrollListener(OnScrollListener)  介绍:void  setPreserveFocusAfterLayout(boolean preserveFocusAfterLayout)  介绍:Set whether the RecyclerView should try to keep the same Item focused after a layout calculation or not.
  • void  setRecycledViewPool(RecyclerView.RecycledViewPool pool)  介绍:Recycled view pools allow multiple多重的 RecyclerViews to share a common pool of scrap废弃的 views.
  • void  setRecyclerListener(RecyclerView.RecyclerListener listener)  介绍:Register a listener that will be notified whenever a child view is recycled.
  • void  setScrollingTouchSlop(int slopConstant)  介绍:Configure the scrolling touch slop益处 for a specific use case.
  • void  setViewCacheExtension(RecyclerView.ViewCacheExtension extension)  介绍:Sets a new RecyclerView.ViewCacheExtension to be used by the Recycler.
  • void  smoothScrollBy(int dx, int dy)  介绍:Animate a scroll by the given amount of pixels along either axis.
  • void  smoothScrollBy(int dx, int dy, Interpolator interpolator)  介绍:Animate a scroll by the given amount of pixels along either axis.
  • void  smoothScrollToPosition(int position)  介绍:Starts a smooth scroll to an adapter position.
  • boolean  startNestedScroll(int axes)  介绍:Begin a nestable scroll operation along the given axes.
  • void  stopNestedScroll()  介绍:Stop a nested scroll in progress进行中的.
  • void  stopScroll()  介绍:Stop any current scroll in progress, such as one started by smoothScrollBy(int, int), fling(int, int) or a touch-initiated fling.
  • void  swapAdapter(Adapter adapter, boolean removeAndRecycleExistingViews)  介绍:Swaps交换 the current adapter with the provided one.



null


RecyclerView 介绍 基本使用