RecyclerView(2) 相关类的功能


RecyclerView相关类

类名
说明
RecyclerView.Adapter

托管数据集合,为每个Item创建视图

RecyclerView.ViewHolder承载Item视图的子视图
RecyclerView.LayoutManager负责Item视图的布局
RecyclerView.ItemDecoration为每个Item视图添加子视图,在Demo中被用来绘制Divider
RecyclerView.ItemAnimator负责添加、删除数据时的动画效果


1.ViewHolder

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

[java]  view plain copy
  1. public class MyViewHolder extends ViewHolder implements OnClickListener,OnLongClickListener{  
  2.   
  3.     public ImageView iv;  
  4.     public TextView tv;  
  5.     private MyItemClickListener mListener;  
  6.     private MyItemLongClickListener mLongClickListener;  
  7.       
  8.     public MyViewHolder(View rootView,MyItemClickListener listener,MyItemLongClickListener longClickListener) {  
  9.         super(rootView);  
  10.         iv = (ImageView)rootView.findViewById(R.id.item_iv);  
  11.         tv = (TextView)rootView.findViewById(R.id.item_tv);  
  12.         this.mListener = listener;  
  13.         this.mLongClickListener = longClickListener;  
  14.         rootView.setOnClickListener(this);  
  15.         rootView.setOnLongClickListener(this);  
  16.     }  
  17.   
  18.     /** 
  19.      * 点击监听 
  20.      */  
  21.     @Override  
  22.     public void onClick(View v) {  
  23.         if(mListener != null){  
  24.             mListener.onItemClick(v,getPosition());  
  25.         }  
  26.     }  
  27.   
  28.     /** 
  29.      * 长按监听 
  30.      */  
  31.     @Override  
  32.     public boolean onLongClick(View arg0) {  
  33.         if(mLongClickListener != null){  
  34.             mLongClickListener.onItemLongClick(arg0, getPosition());  
  35.         }  
  36.         return true;  
  37.     }  
  38.   
  39. }  


2.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
  1. public class MyAdapter extends Adapter<MyViewHolder> {  
  2.   
  3.     private List<MyItemBean> mData;  
  4.     private MyItemClickListener mItemClickListener;  
  5.     private MyItemLongClickListener mItemLongClickListener;  
  6.       
  7.     public MyAdapter(List<MyItemBean> data){  
  8.         this.mData = data;  
  9.     }  
  10.       
  11.     @Override  
  12.     public int getItemCount() {  
  13.         return mData.size();  
  14.     }  
  15.   
  16.       
  17.     @Override  
  18.     public void onBindViewHolder(MyViewHolder holder, int position) {  
  19.         MyItemBean bean = mData.get(position);  
  20.         holder.tv.setText(bean.tv);  
  21.     }  
  22.   
  23.     @Override  
  24.     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  25.         View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent,false);  
  26.         MyViewHolder vh = new MyViewHolder(itemView,mItemClickListener,mItemLongClickListener);  
  27.         return vh;  
  28.     }  
  29. }


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


3.RecyclerView.LayoutManager

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

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

  • public LayoutParams generateDefaultLayoutParams()
Demo中为RecylerView添加LinearLayoutManager的片段:

[java]  view plain copy
  1. MyLayoutManager manager = new MyLayoutManager(this);  
  2.         manager.setOrientation(LinearLayout.HORIZONTAL);//默认是LinearLayout.VERTICAL  
  3.         mRecyclerView.setLayoutManager(manager);  
LinearLayoutManager提供了如下几个方法来帮助开发者获取屏幕上的顶部item和底部item:

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


4.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效果:

[java]  view plain copy
  1. public class MyDecoration extends ItemDecoration {  
  2.   
  3.     private static final int[] ATTRS = new int[]{  
  4.         android.R.attr.listDivider  
  5.     };  
  6.       
  7.     private Drawable mDivider;  
  8.       
  9.     public MyDecoration(Context ctx){  
  10.         final TypedArray a = ctx.obtainStyledAttributes(ATTRS);  
  11.         mDivider = a.getDrawable(0);  
  12.     }  
  13.       
  14.     @Override  
  15.     public void onDraw(Canvas c, RecyclerView parent, State state) {  
  16.         int top = parent.getPaddingTop();  
  17.         int bottom = parent.getHeight() - parent.getPaddingBottom();  
  18.         int childCount = parent.getChildCount();  
  19.         for(int i=0;i < childCount;i++){  
  20.             View child = parent.getChildAt(i);  
  21.             RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams)child.getLayoutParams();  
  22.             int left = child.getRight() + layoutParams.rightMargin;  
  23.             int right = left + mDivider.getIntrinsicWidth();  
  24.             mDivider.setBounds(left, top, right, bottom);  
  25.             mDivider.draw(c);  
  26.         }  
  27.     }  
  28.       
  29.     @Override  
  30.     public void getItemOffsets(Rect outRect, View view, RecyclerView parent,  
  31.             State state) {  
  32.         outRect.set(00, mDivider.getIntrinsicWidth(), 0);  
  33.     }  
  34.       
  35. }  

5.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)



参考资料:

A First Glance at Android’s RecyclerView

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: RecyclerView是一个强大的Android视图组件,它可以用于展示大量的数据列表。然而,默认情况下,RecyclerView是不支持循环滚动的,即当滚动到列表末尾时,无法自动回到列表开头进行循环。 如果我们想要实现RecyclerView的循环滚动,可以采取以下步骤: 1. 添加循环滚动的功能,可以选择使用RecyclerView的扩展,例如LoopRecyclerView,它继承自RecyclerView。 2. 在自定义的LoopRecyclerView中,我们可以通过重写LayoutManager的`scrollToPosition()`方法和`onLayoutCompleted()`方法来实现循环滚动的效果。 3. 在`scrollToPosition()`方法中,我们需要判断滚动到列表末尾时,将滚动位置设置为列表的开头。具体操作是,当滚动到列表末尾时,我们可以通过调用RecyclerView的`getAdapter().getItemCount()`方法获取到列表的总数,然后将滚动位置设置为0,即列表的开头。 4. 在`onLayoutCompleted()`方法中,我们需要监听列表的布局完成事件,在布局完成时判断列表是否滚动到了末尾,如果滚动到了末尾,同样将滚动位置设置为列表的开头,实现循环滚动的效果。 5. 使用我们自定义的LoopRecyclerView替换原来的RecyclerView,并设置相应的适配器和布局管理器,即可实现循环滚动的RecyclerView。 总之,通过继承RecyclerView和重写LayoutManager的相关方法,我们可以实现RecyclerView的循环滚动。这样,当用户滚动到列表末尾时,列表会自动回到开头,实现循环滚动的效果。 ### 回答2: RecyclerView默认是不支持循环滚动的,但可以通过一些方法实现循环滚动效果。 首先,可以创建一个自定义的LayoutManager来实现循环滚动。可以继承LinearLayoutManager或GridLayoutManager,并重写onLayoutChildren()方法来改变布局行为。在onLayoutChildren()方法中,可以通过设置setStackFromEnd(true)来将最后一个item放在顶部,并使用setReverseLayout(true)来反向布局。 其次,需要监听RecyclerView的滚动事件。可以通过addOnScrollListener()方法添加一个滚动监听器,然后在监听器的回调方法中判断当前滚动位置,当滚动到第一个或最后一个item时,通过调用scrollToPosition()方法平滑地滚动到相应的位置。 最后,可以创建一个无限循环的数据源来使RecyclerView实现循环滚动。在Adapter中,可以使用getItemCount()方法返回一个较大的值,然后在getItemViewType()方法中使用求模运算根据位置返回实际的数据项。 总结起来,实现RecyclerView循环滚动的关键步骤包括创建自定义LayoutManager、监听滚动事件、以及创建无限循环的数据源。这样就可以让RecyclerView实现似ViewPager一样的循环滚动效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值