“A flexible view for providing a limited window into a large data set.”

可以说是ListView的升级版,ListVie中我们需要自己写ViewHolder,当然你也可以不写,是在RecylerView中,是要让写的哟~RecyclerView适用于无法在一个屏幕范围内展现格式一样的数据时,需要用多行或多列来展示。例如展示联系人,图片,视频等。用户需要滑动屏幕来查看数据,这时RecyclerView的特性就有用武之地了。比如,当用户滑动使当前一个可视的Item滑出屏幕,这个Item的视图将会被回收并在一个新Item进入可视范围后重新被使用。可回收利用View是个很实用的功能,它不仅可以减少CPU不断inflate View的开销,而且可以节省缓存View的内存开销。

RecylerView还有一大特色,就是动画!

RecyclerView不再负责显示工作

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

  <td valign="top" width="454">
    托管数据集合,为每个Item创建视图
  </td>
</tr>

<tr>
  <td valign="top" width="326">
    RecyclerView.ViewHolder
  </td>
  
  <td valign="top" width="454">
    承载Item视图的子视图
  </td>
</tr>

<tr>
  <td valign="top" width="326">
    RecyclerView.LayoutManager
  </td>
  
  <td valign="top" width="454">
    负责Item视图的布局
  </td>
</tr>

<tr>
  <td valign="top" width="326">
    RecyclerView.ItemDecoration
  </td>
  
  <td valign="top" width="454">
    为每个Item视图添加子视图,在Demo中被用来绘制Divider
  </td>
</tr>

<tr>
  <td valign="top" width="326">
    RecyclerView.ItemAnimator
  </td>
  
  <td valign="top" width="454">
    负责添加、删除数据时的动画效果
  </td>
</tr>
RecyclerView.Adapter

ViewHolder

关于ViewHolder,Google早就推荐开发者使用,但也只是建议。但是现在,RecyclerView.Adapter最终要求开发者必须使用ViewHolder。

public class MyViewHolder extends ViewHolder{  

  public ImageView iv;  
  public TextView tv;  
    
  public MyViewHolder(View rootView) {  
      super(rootView);  
      iv = (ImageView)rootView.findViewById(R.id.item_iv);  
      tv = (TextView)rootView.findViewById(R.id.item_tv);  
  }  

}

RecyclerView.Adapter

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

public class MyAdapter extends Adapter&lt;MyViewHolder&gt; {  

  private List&lt;Item&gt; mData;  
    
  public MyAdapter(List&lt;Item&gt; data){  
      this.mData = data;  
  }  
    
  @Override  
  public int getItemCount() {  
      return mData.size();  
  }  

    
  @Override  
  public void onBindViewHolder(MyViewHolder holder, int position) {  
      Item 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);  
      return vh;  
  }
}

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

RecyclerView.LayoutManager

LayoutManager是RecyclerView中最有意思的类。该类负责将每个Item视图在RecylerView中的布局。目前Google提供了LayoutManager的一个子类:LinearLayoutManager。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并调用各自的绘图方法。

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 &lt; 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);  
}  

}

      
      <div class="cnblogs_code_toolbar">
        <span class="cnblogs_code_copy"><a title="复制代码">![复制代码](http://common.cnblogs.com/images/copycode.gif)</a></span>
      </div>
    </div>
    
    ## RecyclerView.ItemAnimatior
    
      * 删除某一个Item
      * 添加一个新的Item
      * 移动某个Item
    
    Google提供了一个名为DefaultItemAnimator的默认ItemAnimator供开发者使用。如果开发者不为RecyclerView设置ItemAnimator,RecyclerView也会使用默认的DefaultItemAnimator。  
    显然,为了让动画效果起效,开发者必须通知Adapter数据有改变。之前我们使用Adapter时会调用notifyDataSetChanged()来通知Adapter数据改变并更新视图,现在RecyclerView,Adapter提供了许多notifyXyz()方法。
    
    ## 流程
    
      * 实例化RecyclerView
      * 为RecyclerView设置LayoutManager
      * 为RecyclerView设置Adapater
      * 如果有需求,可以设置一个或多个ItemDecorations,当然,也可以不设置
      * 如果有需求,可以设置ItemAnimator
    ## 监听事件
    
    RecyclerView不再负责Item视图的布局及显示,所以RecyclerView也没有为Item开放OnItemClick等点击事件,这就需要开发者自己实现。
    
    因为ViewHolder我们可以拿到每个Item的根布局,所以如果我们为根布局设置单独的OnClick监听并将其开放给Adapter,那不就可以在组装RecyclerView时就能够设置ItemClickListener,只不过这个Listener不是设置到RecyclerView上而是设置到Adapter。
    
    <div class="cnblogs_code">
      <div class="cnblogs_code_toolbar">
        <span class="cnblogs_code_copy"><a title="复制代码">![复制代码](http://common.cnblogs.com/images/copycode.gif)</a></span>
      </div>
      
      ```
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;  
    }  
  
}
  <div class="cnblogs_code_toolbar">
    <span class="cnblogs_code_copy"><a title="复制代码">![复制代码](http://common.cnblogs.com/images/copycode.gif)</a></span>
  </div>
</div>

## item长宽

<div class="cnblogs_code">
  <div class="cnblogs_code_toolbar">
    <span class="cnblogs_code_copy"><a title="复制代码">![复制代码](http://common.cnblogs.com/images/copycode.gif)</a></span>
  </div>
  
  ```

public class MyLayoutManager extends LinearLayoutManager {

public MyLayoutManager(Context context) {  
    super(context);  
}  
  

@Override  
public void onMeasure(Recycler recycler, State state, int widthSpec,int heightSpec) {  
    View view = recycler.getViewForPosition(0);  
    if(view != null){  
        measureChild(view, widthSpec, heightSpec);  
        int measuredWidth = MeasureSpec.getSize(widthSpec);  
        int measuredHeight = view.getMeasuredHeight();  
        setMeasuredDimension(measuredWidth, measuredHeight);  
    }  
}  

}

      
      <div class="cnblogs_code_toolbar">
        <span class="cnblogs_code_copy"><a title="复制代码">![复制代码](http://common.cnblogs.com/images/copycode.gif)</a></span>
      </div>
    </div>
    
    参考:http://www.grokkingandroid.com/first-glance-androids-recyclerview/ 
    
      * 转自:http://www.cnblogs.com/yydcdut/p/4470225.html?utm_source=tuicool