RecyclerView详解
来源:互联网 发布:哪个软件容易泡妞 编辑:程序博客网 时间:2024/06/05 17:50
RecyclerView详解
一 集成: 必须手动导入带有RecyclerView的V7包
二 结构:
RecyclerView.Adapter: 创建View并将数据集合绑定到View上
ViewHolder: 持有所有的用于绑定数据或者需要操作的View
LayoutManager: 布局管理器,负责摆放视图等相关操作
ItemDecoration: 负责绘制Item附近的分割线,通过RecyclerView.addItemDecoration()使用
ItemAnimator: 为Item的操作添加动画效果,如,增删条目等,通过RecyclerView.setItemAnimator(new DefaultItemAnimator());使用
三 RecyclerView的内置管理器
· LinearLayoutManager:以垂直或水平滚动列表方式显示项目。类似Listview
· GridLayoutManager: 在网格中显示项目。 类似GridView
· StaggeredGridLayoutManager: 在分散对齐网格中显示项目 瀑布流
继承RecyclerView.LayoutManager
就可以创建自定义的布局管理器。
四 RecyclerView.ItemDecoration是一个抽象类,可以通过重写以下三个方法,来实现Item之间的偏移量或者装饰效果:
public void onDraw(Canvas c, RecyclerViewparent) 装饰的绘制在Item条目绘制之前调用,所以这有可能被Item的内容所遮挡
public void onDrawOver(Canvas c, RecyclerViewparent) 装饰的绘制在Item条目绘制之后调用,因此装饰将浮于Item之上
public void getItemOffsets(Rect outRect,int itemPosition, RecyclerView parent) 与padding或margin类似,LayoutManager在测量阶段会调用该方法,计算出每一个Item的正确尺寸并设置偏移量。
五 ItemAnimator触发于以下三种事件:
某条数据被插入到数据集合中
从数据集合中移除某条数据
更改数据集合中的某条数据
在之前的版本中,当时据集合发生改变时通过调用notifyDataSetChanged(),来刷新列表,因为这样做会触发列表的重绘,所以并不会出现任何动画效果,因此需要调用一些以notifyItem*()作为前缀的特殊方法,比如:
public final void notifyItemInserted(intposition) 向指定位置插入Item
public final void notifyItemRemoved(intposition) 移除指定位置Item
public final void notifyItemChanged(intposition) 更新指定位置Item
六优点它自带ViewHolder来实现View的复用机制,再也不用ListView那样在getView()里自己写了
使用LayoutManager可以实现ListView,GridView以及流式布局的列表效果
通过setItemAnimator(ItemAnimator animator)可以实现增删动画(懒的话,可以使用默认的ItemAnimator对象,效果也不错)
控制item的间隔,可以使用addItemDecoration(ItemDecoration decor),不过里边的ItemDecoration是一个抽象类,需要自己去实现
七RecyclerView的常用方法
1 GetChildCount(); //获取可见的item数量
2. findViewHolderForAdapterPosition //获取position处item绑定的viewHolder
3 设置固定大小 recyclerView_one.setHasFixedSize(true);布局管理器之GridLayoutManager
一构造方法GridLayoutManager,网格布局(流式布局应该是它的一个特殊情况):
GridLayoutManager(Context context, int spanCount)或
GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout)
1 Context context上下文
2 int spanCount 显示的个数
3 int orientation 显示的类型 默认为vertical
LinearLayoutManager.VERTICAL 整体竖直排列一行显示参数二设置的个数
LinearLayoutManager.HORIZONTAL 整体水平排一列显示spanCount 个数据
4 boolean reverseLayout最后一个参数表示的是是否逆向布局(意思是将数据反向显示,原先从左向右,从上至下。设为true之后全部逆转)。
小提示:在这两个LayoutManager中,默认的orientation为vertical,reverseLayout为false。对应的参数在GridLayoutManager中都有对应的方法来进行补充设置。而在StaggeredGridLayoutManager中所有的方法都针对reverseLayout做了判断,然而它并没有给出这个参数设定值的api。
二常用实现复杂列数变化的方法 根据position控制每列显示的多少
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return 4 ? mGridLayoutManager.getSpanCount() : 1; }});
当前position为4吗 不为4 每设置的显示类型每行【或列】显示构造方法里设置的个数【mGridLayoutManager.getSpanCount()获取GridLayoutManager设置的个数】 为4该下标position显示一条数据每行【或列】
布局管理器之LinearLayoutManager可见性:在RecyclerView里可见性的定义指的是Item露出一部分,,这个Item就是可见性的
完全可见性:指的是整个Item都可以在屏幕里展示出来,,没有被别的控件遮挡
一常用方法
1findFirstVisibleItemPosition(); 获取第一个可见item的pisition
2findFirstCompletelyVisibleItemPosition();获取第一个完全可见item的position
3findLastVisibleItemPosition(); 获取最后第一个可见item的pisition
4findFirstCompletelyVisibleItemPosition();获取最后一个完全可见item的position
5.setOrientation(OrientationHelper.VERTICAL); //设置垂直方向
瀑布流管理器
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));
这样就和GridLayoutManager实现一样的效果了
瀑布流效果在适配器设置其高度不一致即可
一RecyclerView.ItemDecoration是一个抽象类,可以通过重写以下三个方法,来实现Item之间的偏移量或者装饰效果:
方法一: public void onDraw(Canvas c, RecyclerViewparent) 装饰的绘制在Item条目绘制之前调用,所以这有可能被Item的内容所遮挡
方法二: public voidonDrawOver(Canvas c, RecyclerView parent) 装饰的绘制在Item条目绘制之后调用,因此装饰将浮于Item之上、
public class ItemDecor extends RecyclerView.ItemDecoration { Paint mPaint; public ItemDecor() { mPaint = new Paint(); mPaint.setColor(0x99FF0000);}//此等装饰物在 item绘制之后调用 在item之上 @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { c.drawCircle(50, 30, 30, mPaint); }}
//使用这个方法画分割线 需要通过遍历给每个条目画
public class ItemDecorationRec extends RecyclerView.ItemDecoration{ //声明画笔 Paint mPaint; //构造函数初始化画笔 public ItemDecorationRec() { mPaint = new Paint(); mPaint.setColor(0x99FF0000); } //上边画圆 @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { 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); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child)); final int bottom = top + 50; c.drawRect(left, top, right, bottom, mPaint); }// c.drawCircle(50, 30, 30, mPaint); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.set(0,0,0,70); }}方法三
public voidgetItemOffsets(Rect outRect, intitemPosition, RecyclerView parent) 与padding或margin类似,LayoutManager在测量阶段会调用该方法,计算出每一个Item的正确尺寸并设置偏移量。
参数一:我们通过设置outRect的left, top, right, bottom属性值就可以让ItemView产生相应的偏移(内嵌),
上述方法的调用顺序,先执行ItemDecoration的onDraw()、再执行ItemView的onDraw()、再执行ItemDecoration的onDrawOver()。由于和RecyclerView使用的是同一个Canvas,所以你想在Canvas上画什么都可以,就像我们平时自定义View时写onDraw()方法一样。
二 使用:自定义类itemDecoration继承RecyclerView.ItemDecoration重写上面三个方法即可
然后调用mRecycler.addItemDecoration(new ItemDecorationRec());即可给条目添加间隔 【可重复添加addItemDecoration】
三 使用系统自带的画分割线
public class SystemDecoration extends RecyclerView.ItemDecoration { //采用系统内置的风格的分割线 private static final int[] attrs=new int[]{android.R.attr.listDivider}; private Drawable mDivider; private int orientation; //定向横向还是竖向的 /** * 系统自制分割线 参数二是orientation传入横向还是纵向的 */ public SystemDecoration(Context context,int orientation) { TypedArray typedArray=context.obtainStyledAttributes(attrs); mDivider=typedArray.getDrawable(0); typedArray.recycle(); this.orientation=orientation; } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { drawHDeraction(c,parent); drawVDeraction(c,parent); } /** * 绘制水平方向的分割线 * @param c * @param parent */ private void drawHDeraction(Canvas c,RecyclerView parent){ int left=parent.getPaddingLeft(); int right=parent.getWidth()-parent.getPaddingRight(); int childCount=parent.getChildCount(); for(int i=0;i<childCount;i++){ View child=parent.getChildAt(i); RecyclerView.LayoutParams layoutParams=(RecyclerView.LayoutParams)child.getLayoutParams(); int top=child.getBottom()+layoutParams.bottomMargin; int bottom=top+mDivider.getIntrinsicHeight(); mDivider.setBounds(left,top,right,bottom); mDivider.draw(c); } } /** * 绘制垂直方向的分割线 * @param c * @param parent */ private void drawVDeraction(Canvas c,RecyclerView parent){ 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, RecyclerView.State state) { if(OrientationHelper.HORIZONTAL==orientation){ outRect.set(0, 0,mDivider.getIntrinsicWidth(), 0); }else { outRect.set(0, 0, 0,mDivider.getIntrinsicHeight()); } }}}调用:recyclerView_one.addItemDecoration(newAdvanceDecoration(this,OrientationHelper.VERTICAL))
GrideDecoration 网格布局用的分割线
public class grideDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; private Drawable mDivider; public grideDecoration(Context context) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { drawHorizontal(c, parent); drawVertical(c, parent); } private int getSpanCount(RecyclerView parent) { // 列数 int spanCount = -1; RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { spanCount = ((StaggeredGridLayoutManager) layoutManager) .getSpanCount(); } return spanCount; } public void drawHorizontal(Canvas c, RecyclerView parent) { 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.getLeft() - params.leftMargin; final int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } public void drawVertical(Canvas c, RecyclerView parent) { 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 top = child.getTop() - params.topMargin; final int bottom = child.getBottom() + params.bottomMargin; final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicWidth(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) { RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边 { return true; } } else if (layoutManager instanceof StaggeredGridLayoutManager) { int orientation = ((StaggeredGridLayoutManager) layoutManager) .getOrientation(); if (orientation == StaggeredGridLayoutManager.VERTICAL) { if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边 { return true; } } else { childCount = childCount - childCount % spanCount; if (pos >= childCount)// 如果是最后一列,则不需要绘制右边 return true; } } return false; } private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) { RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { childCount = childCount - childCount % spanCount; if (pos >= childCount)// 如果是最后一行,则不需要绘制底部 return true; } else if (layoutManager instanceof StaggeredGridLayoutManager) { int orientation = ((StaggeredGridLayoutManager) layoutManager) .getOrientation(); // StaggeredGridLayoutManager 且纵向滚动 if (orientation == StaggeredGridLayoutManager.VERTICAL) { childCount = childCount - childCount % spanCount; // 如果是最后一行,则不需要绘制底部 if (pos >= childCount) return true; } else // StaggeredGridLayoutManager 且横向滚动 { // 如果是最后一行,则不需要绘制底部 if ((pos + 1) % spanCount == 0) { return true; } } } return false; } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { int spanCount = getSpanCount(parent); int childCount = parent.getAdapter().getItemCount(); if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部 { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边 { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight()); } }}ItemAnimator
1// 设置item默认动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
RecyclerAdapte
一Recycler.Adapter中的数据的添加和删除
例如我们在使用ListView的时候,当数据发生变化的时候可以通过notifyDatasetChange()来刷新界面。对于RecyclerView控件来讲,给我们提供更加高级的使用方法notifyItemInserted(position)和notifyItemRemoved(position)
我们可以在TestRecyclerAdapter中添加数据新增和数据删除的方法如下:
//添加数据 public void addItem(String data, intposition) { mTitles.add(position, data); notifyItemInserted(position); }在运行之前我们不要忘记RecyclerView给提供了动画设置,我这边就直接采用了默认动画,设置方法如下://删除数据
public void removeItem(String data) {
int position = mTitles.indexOf(data);
mTitles.remove(position);
notifyItemRemoved(position);
}
//添加默认的动画效果
recyclerView_one.setItemAnimator(new DefaultItemAnimator());
二适配器的实现方法
//自定义适配器 继承 RecyclerView.Adapter 重写几个方法public class MyRecyclerAdapter extends RecyclerView.Adapter { private static final int ITEM_VIEW_TYPE_HEADER = 12; private static final int ITEM_VIEW_TYPE_ITEM = 1; private List<MOdule> list;// private Context context; private List<Activity> activityList;//activity的集合 private BitmapUtils bitmapUtils; private int w;//屏幕宽度 private int size;//添加空白item的集合长度 private User_login user; ViewHolder viewHolderholder; Holder mholder; public boolean isHeader(int position) { return position == 12; } /** * 适配器的构造函数 */ public MyRecyclerAdapter(List<MOdule> list, Context context, int w, List<Activity> activityList, int size) { this.list = list; this.context = context; this.w = w; this.activityList = activityList; this.size = size; } /** * onCreateViewHolder会调用这个根据position获取该位置下 条目的类型 然后onCreateViewHolder根据type分别创建holder */ @Override public int getItemViewType(int position) { if (position == 12) { return ITEM_VIEW_TYPE_HEADER; } else { return ITEM_VIEW_TYPE_ITEM; } } /** * 是用来配合写好的ViewHolder来返回一个ViewHolder对象。这里也涉及到了条目布局的加载。viewType则表示需要给当前position生成的是哪一种ViewHolder,这个参数也说明了RecyclerView对多类型ItemView的支持。 */ @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_VIEW_TYPE_HEADER) { //ViewPager的布局 View itemview_item2 = LayoutInflater.from(context).inflate(R.layout.recycler_item2, parent, false); mholder = new Holder(itemview_item2); ViewGroup.LayoutParams params = mholder.itemView.getLayoutParams(); params.width = w; params.height = (int) ((1f / 4f) * w); return mholder; } else { //创建普通的方块+ final Context context = parent.getContext(); //GridView的布局 View itemview_item1 = LayoutInflater.from(context).inflate(R.layout.recycler_item1, parent, false); viewHolderholder = new ViewHolder(itemview_item1); return viewHolderholder; } } /** * 专门用来绑定ViewHolder里的控件和数据源中position位置的数据。 */ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { if (position != ITEM_VIEW_TYPE_HEADER && position < list.size() - size) { viewHolderholder = (ViewHolder) holder; /** * 通过viewHolderholder.itemView. 设置条目的长按点击事件 */ viewHolderholder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { //添加震动 Vibrator vibrator = (Vibrator) (context.getSystemService(Context.VIBRATOR_SERVICE)); long[] pattern = {20, 50}; vibrator.vibrate(pattern, -1); //添加缩放动画// ScaleAnimation animation=new ScaleAnimation(1.0f,1.2f,1.0f,1.2f);// animation.setDuration(200);// animation.setFillAfter(false);// v.startAnimation(animation); // v.setBackgroundColor(Color.parseColor("#E8E6E8")); //记录位置表示有长按操作 SharedPreferencesUtil.putInt("recycler_position", position, context); return false; } }); /** * 通过viewHolderholder.itemView. 设置条目的点击事件 */ viewHolderholder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int recycler_position = SharedPreferencesUtil.getInt("recycler_position", context); } }); tv.setText(list.get(position).getModuleName()); } else if (position == ITEM_VIEW_TYPE_HEADER) { mholder = (Holder) holder; } } /** * getItemCount()就不必多说了,和ListView是一样的 条目的总个数 */ @Override public int getItemCount() { return list.size(); } /** * GridView 每个方块的 ViewHolder 把inflate后的view传入 * */ class ViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder { private View view; public ViewHolder(View itemView) { super(itemView); this.view = itemView; } public View getView() { return view; } @Override public void onItemSelected() { // 当选中时,背景色为灰色 itemView.setBackgroundColor(Color.LTGRAY); } @Override public void onItemClear() { //当拖拽完毕后,背景色为透明 itemView.setBackgroundColor(0); } } /** * ViewPager * Holder */ class Holder extends RecyclerView.ViewHolder { public Holder(View itemView) { super(itemView); } }}三 adapter中的数据的重新处理
class MyViewHolder extends ViewHolder{ TextView tv; //构造里执行findviewByid public MyViewHolder(Context context, View view){ super(view); tv = (TextView) view.findViewById(R.id.id_num); //当然,我们也可以在这里使用view来对RecyclerView的一个item进行事件监听,也可以使用 //tv等子控件来实现item的子控件的事件监听。这也是我之所以要传context的原因之一呢~ ...... } //创建实例的时候 填充布局 public static MyViewHolder newInstance(Activity context, ViewGroup parent){ View view = LayoutInflater.from( context).inflate(R.layout.item_home, parent,false); return new MyViewHolder(context, view); } } //你没看错,数据绑定也被整合进来了, //将adapter里的数据根据position获取到后传进来。当然,也可以根据具体情况来做调整。 public void onBinViewHolder(String data){ tv.setText(data);//既然这里也有子控件,那么这里也可以做item子控件的事件监听喽}Adapter
class HomeAdapter extends RecyclerView.Adapter<MyViewHolder>{ @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){//如需要,还要对viewType做判断 return MyViewHolder.newInstance(this, parent) } @Override public void onBindViewHolder(MyViewHolder holder, int position){ holder.onBindViewHolder(mDatas.get(position)); } @Override public int getItemCount(){ return mDatas.size(); }}
ItemTouchHelper实现Recycler的滑动和拖动
1、ItemTouchHelper 支持RecyclerView滑动删除和拖拽的工具类
一结合recyvlerVIew的使用方法为:
//1设置一个ItemTouchHelper.Callback对象
ItemTouchHelper.Callback callback = newItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT| ItemTouchHelper.LEFT, 0)
//2创建 ItemTouchHelper对象 传入callBack
ItemTouchHelper itemTouchHelper=newItemTouchHelper(callback);
//3让item的图所动滑动依附在RecyclerView上
itemTouchHelper.attachToRecyclerView(mRecycler)
二 SimpleCallback方法
SimpleCallback构造方法需要我们传入两个参数:
1、dragDirs - 表示拖拽的方向,有六个类型的值:LEFT、RIGHT、START、END、UP、DOWN
2、swipeDirs - 表示滑动的方向,有六个类型的值:LEFT、RIGHT、START、END、UP、DOWN
这两个参数如果为0表示不执行此操作
//1设置一个ItemTouchHelper.Callback对象 ItemTouchHelper.Callback callback = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT, 0) { /** * @param recyclerView * @param viewHolder 拖动的ViewHolder * @param target 目标位置的ViewHolder * @return */ @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { int fromPosition = viewHolder.getAdapterPosition();//得到拖动ViewHolder的position int toPosition = target.getAdapterPosition();//得到目标ViewHolder的position if (fromPosition < toPosition) { //分别把中间所有的item的位置重新交换 for (int i = fromPosition; i < toPosition; i++) { Collections.swap(datas, i, i + 1); } } else { for (int i = fromPosition; i > toPosition; i--) { Collections.swap(datas, i, i - 1); } } mAdapter.notifyItemMoved(fromPosition, toPosition); //返回true表示执行拖动 return true; } /** * 滑动时执行该方法 执行删除 */ @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { int position = viewHolder.getAdapterPosition(); datas.remove(position); mAdapter.notifyItemRemoved(position); } /** * getMovementFlags ()返回支持哪些方向的事件(貌似拖动排序事件和左右滑动事件不能同时支持,拖动会覆盖左右滑动) * 该方法第一个被调用 可加判断哪些可以拖动滑动 哪些不可以 */ @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { Log.d("flag","-------------------------getMovementFlags执行了"); if (viewHolder.getAdapterPosition() == 12 || viewHolder.getAdapterPosition() > moduleListSize - 1) { return makeMovementFlags(0, 0); //第13个轮播 和空白页不能操作 } else { if (recyclerView.getLayoutManager() instanceof GridLayoutManager) { final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; final int swipeFlags = 0; return makeMovementFlags(dragFlags, swipeFlags); //gridLayout不能滑动只能拖动 } else { final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags); } } } /** * 来改变动画效果,细心的会发现上图在滑动时候并没有透明感,于是我们可以实现onChildDraw()方法,该方法用于Item的绘制,actionState有三种状态SWIPE(滑动)、IDLE(静止)、DRAG(拖动) */ @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); Log.d("flag", "-------------------------onChildDraw执行了"); if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { //ACTION_STATE_SWIPE是滑动的时候 改变透明度 //左右滑动时改变Item的透明度(没用到) final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth(); viewHolder.itemView.setAlpha(alpha); viewHolder.itemView.setTranslationX(dX); } } /** * //当选中Item时候会调用该方法,重写此方法可以实现选中时候的一些动画逻辑 * 第二个调用 */ @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); Log.d("flag", "-------------------------onSelectedChanged执行了"); //长按 设置了放大的动画效果 if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { viewHolder.itemView.setScaleX(1.2f); viewHolder.itemView.setScaleY(1.2f); } } /** * //当动画已经结束的时候调用该方法,重写此方法可以实现恢复Item的初始状态 */ @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); Log.d("flag", "------------------------clearView执行了"); //还原动画 viewHolder.itemView.setBackgroundResource(R.drawable.background_drag); viewHolder.itemView.setScaleX(1.0f); viewHolder.itemView.setScaleY(1.0f); adapter.notifyDataSetChanged();//没看出什么用 }}
- RecyclerView详解
- RecyclerView详解
- RecyclerView详解
- RecyclerView详解
- RecyclerView详解
- RecyclerView详解
- recyclerview详解
- RecyclerView详解
- RecyclerView详解
- RecyclerView详解
- RecyclerView详解
- RecyclerView详解
- RecyclerView详解
- First RecyclerView (RecyclerView使用详解)
- RecyclerView 的使用详解
- Android RecyclerView 使用详解
- RecyclerView简单详解
- RecyclerView分割线详解
- 第一阶段第十一天(String字符串 和StringBuffer)
- 标签栏TabLayout与ViewPager的那些事
- Druid评测
- IDEA自定义新建文件自动产生的userName
- sqlserver数据库 去除字段中空格,换行符,回车符(使用replace语句)
- RecyclerView详解
- echart asp.net 在服务器端 批量导出图表到指定文件夹
- 分析Android帧缓冲区状态监控过程
- String、StringBuffer与StringBuilder之间区别
- 数论概论第二章
- 在Android Studio中讲一个module作为另一个module的依赖
- Java构造器和方法的区别
- jdk自带压缩乱码
- xampp设置外网访问