💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
>还在用Lisview?RecyclerView都已经出来一年多了! 想必大家多或多或少的接触过或者了解过RecyclerView,为什么没有用起来,原因大概如下? - **ListView我用的挺好的,为什么要换RecyclerView?** - **ListView稳定,熟悉,还知道很多开源库,特别的好用!** - **RecyclerView不能添加头部,ListView能!** ------------------- ## RecyclerView >RecyclerView最大的优势就是灵活,RecyclerView只需改变一行代码就可以变化多种不同的布局显示排版,这一点对于开发者是非常方便的! >>还有RecyclerView.Adapter,比BaseAdapter做了更好的封装,把BaseAdapter的getView方法拆分成onCreateViewHolder方法和onBindViewHolder方法,强制需要创建ViewHolder,这样的好处就是避免了初学者写性能不佳的代码 在Andorid 5.0出来不久,我就已经写过RecyclerView的简单介绍以及基本使用,不了解的可以看看[ListView升级版RecyclerView](http://blog.csdn.net/cym492224103/article/details/41719497),了解过的同学可以忽略,并往下看。 ## 在实战中我们会遇到什么问题? >get到下面的技能就能够在使用RcyclerView的大路上畅通无阻了! - **添加分割线** - **添加点按效果** - **列表动画** - **改变某个数据保持当前位置** - **添加头部尾部** - **列表分组** - **各种效果集成Demo** - **更灵活的RecyclerView** ####添加分割线 ``` //通过以下方法添加分割线 mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); ``` 需要RecyclerView.ItemDecoration这个抽象类实现一些方法 (后续有更偷懒的方法) ``` /** * This class is from the v7 samples of the Android SDK. It's not by me! * <p/> * See the license above for details. */ public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{ android.R.attr.listDivider }; public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; private Drawable mDivider; private int mOrientation; public DividerItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); setOrientation(orientation); } public void setOrientation(int orientation) { if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { throw new IllegalArgumentException("invalid orientation"); } mOrientation = orientation; } @Override public void onDraw(Canvas c, RecyclerView parent) { Log.v("recyclerview - itemdecoration", "onDraw()"); if (mOrientation == VERTICAL_LIST) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } public void drawVertical(Canvas c, RecyclerView parent) { final int left = parent.getPaddingLeft(); final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext()); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } public void drawHorizontal(Canvas c, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } } } ``` 看到这里应该有同学吐槽了,就添加一根线至于吗?还需要重写方法,ListView可是只需要简单配置一下就好了。 ``` android:divider="@color/grey" android:dividerHeight="5dp" ``` 为此我也感觉太麻烦,于是我想了一个办法: **直接在item_view里面底部自己添加一根线布局,这样就无需重写了,并且这样还有个好处就是,如果细心的同学会发现,添加分割线,最后一个item下面不会有分割线,显然当数据量不足一个屏幕的时候显得很突兀,但是在item_view下面添加一个线的布局则不会出现这种情况** ####添加点按效果 RecyclerView直接在item_view里面配置即可 ####动画 >一个好的用户体验就是要有操作动画的过渡,而不是生硬的刷新列表。 >>推荐一个RecyclerView的动画库([recyclerview-animators](https://github.com/wasabeef/recyclerview-animators)) >![这里写图片描述](https://github.com/wasabeef/recyclerview-animators/raw/master/art/demo2.gif) RecyclerView自带添加、删除动画,而ListView则需添加额外的代码才能实现。 - **删除调用RecyclerView的adapter的notifyItemRemoved** - **添加调用RecyclerView的adapter的notifyItemInserted** 说到adapter我们就来说说RecyclerView.Adapter和BaseAdapter相比,额外提供了一下这些方法: ``` // 数据发生了改变,那调用这个方法,传入改变对象的位置。 public final void notifyItemChanged(int position); // 可以刷新从positionStart开始itemCount数量的item了 public final void notifyItemRangeChanged(int positionStart, int itemCount); // 添加,传入对象的位置。 public final void notifyItemInserted(int position); // 删除,传入对象的位置。 public final void notifyItemRemoved(int position); // 对象从fromPosition移动到toPosition public final void notifyItemMoved(int fromPosition, int toPosition); //批量添加 public final void notifyItemRangeInserted(int positionStart, int itemCount); //批量删除 public final void notifyItemRangeRemoved(int positionStart, int itemCount); ``` ####改变列表某个布局状态且保持当前位置 这种需求是普遍存在的,就是改变列表某一个item数据,然后刷新列表,如果是ListView刷新后则会回到最顶部,而RecyclerView同样的操作但是原来滑动的位置不变。 ##各种解决方案的RecyclerView的Adapter [BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper) ![效果展示](http://upload-images.jianshu.io/upload_images/972352-c7858feebce4b8fe.gif?imageMogr2/auto-orient/strip) ####更灵活的RecyclerView [twoway-view](https://github.com/lucasr/twoway-view) 封装了RecyclerView常用方法,如click等等,以及支持了更多不同的布局,使得RecyclerView使用起来更简单! ![这里写图片描述](https://github.com/lucasr/twoway-view/raw/master/images/sample.png) >造起来!小伙伴们! 原文地址:[http://blog.csdn.net/cym492224103/article/details/51094982](http://blog.csdn.net/cym492224103/article/details/51094982)