大佬教程收集整理的这篇文章主要介绍了Android开发中RecyclerView模仿探探左右滑动布局功能,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我在此基础上优化了部分代码,添加了滑动回调,可自定义性更强. 并且添加了点击按钮左右滑动的功能.
据说无图都不敢发文章了.
看图:
1:这种功能,首先需要自己管理布局
继承 RecyclerView.LayoutManager
,显示自己管理布局,比如最多显示4个view,并且都是居中显示.
底部的View还需要进行缩放,平移操作.
public class OverLay@L_724_11@manager extends RecyclerView.LayoutManager { private static final String TAG = "swipecard"; public static int MAX_SHOW_COUNT = 4; public static float SCALE_GAP = 0.05f; public static int TRANS_Y_GAP; public OverLay@L_724_11@manager(Context context) { //平移时,需要用到的参考值 TRANS_Y_GAP = (@R_618_10185@ (20 * context.getresources().getDisplaymetrics().density); } @Override public RecyclerView.LayoutParams generateDefaultLayoutParams() { //必须要实现的方法 return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); } @Override public void onLayoutChildren(RecyclerView.Recycler recycler,RecyclerView.State statE) { //在这个方法中进行View的布局操作.此方法会被调用多次. detachAndScrapAttachedViews(recycler); int itemCount = getItemCount(); if (itemCount < 1) { return; } //top-3View的position int bottomPosition; //边界处理 if (itemCount < MAX_SHOW_COUNT) { bottomPosition = 0; } else { bottomPosition = itemCount - MAX_SHOW_COUNT; } //从可见的最底层View开始layout,依次层叠上去 for (int position = bottomPosition; position < itemCount; position++) { //1:重recycler的缓存机制中拿到一个View View view = recycler.getViewForPosition(position); //2:和自定义viewGroup一样,需要先addView addView(view); //3:和自定义viewGroup一样,也需要测量View的大小 measureChildWithMargins(view,0); int widthSpace = getWidth() - getDecoratedMeasuredWidth(view); int heightSpace = getHeight() - getDecoratedMeasuredHeight(view); //4:和自定义viewGroup的onLayout一样,需要layout View.对View进行布局 //我们在布局时,将childView居中处理,这里也可以改为只水平居中 layoutDecoratedWithMargins(view,widthSpace / 2,heightSpace / 2,widthSpace / 2 + getDecoratedMeasuredWidth(view),heightSpace / 2 + getDecoratedMeasuredHeight(view)); /** * TopView的Scale 为1,translationY 0 * 每一级Scale相差0.05f,translationY相差7dp左右 * * 观察人人影视的UI,拖动时,topView被拖动,Scale不变,一直为1. * top-1View 的Scale慢慢变化至1,translation也慢慢恢复0 * top-2View的Scale慢慢变化至 top-1View的Scale,translation 也慢慢变化只top-1View的translation * top-3View的Scale要变化,translation岿然不动 */ //第几层,举例子,count =7, 最后一个TopView(6)是第0层, int level = itemCount - position - 1; //如果不需要缩放平移,那么下面的代码可以注释掉... //除了顶层不需要缩小和位移 if (level > 0 /*&& level < mShowCount - 1*/) { //每一层都需要X方向的缩小 view.setScaleX(1 - SCALE_GAP * level); //前N层,依次向下位移和Y方向的缩小 if (level < MAX_SHOW_COUNT - 1) { view.setTranslationY(TRANS_Y_GAP * level); view.setScaleY(1 - SCALE_GAP * level); } else {//第N层在 向下位移和Y方向的缩小的成都与 N-1层保持一致 view.setTranslationY(TRANS_Y_GAP * (level - 1)); view.setScaleY(1 - SCALE_GAP * (level - 1)); } } } } }
2:布局好了之后,就需要监听鼠标事件了
谷歌官方提供了一个itemtouchhelper工具类,对滑动进行了惨无人道的优越封装,傻x都能用…
使用方法: new itemtouchhelper(callBACk).attachToRecyclerView(recyclerView);
就这么简单,
接下来的操作,都在回调callBACk里面进行.
public class RenRenCallBACk extends itemtouchhelper.SimpleCallBACk { private static final String TAG = "RenRen"; private static final int MAX_ROTATION = 15; OnSwipeListener mSwipeListener; Boolean isSwipeAnim = false; public RenRenCallBACk() { //第一个参数决定可以拖动排序的方向,这里由于不需要拖动排序,所以传0 //第二个参数决定可以支持滑动的方向,这里设置了上下左右都可以滑动. super(0,itemtouchhelper.DOWN | itemtouchhelper.UP | itemtouchhelper.LEFT | itemtouchhelper.RIGHT); } public void setSwipeListener(OnSwipeListener swipeListener) { mSwipeListener = swipeListener; } //水平方向是否可以被回收掉的阈值 public float getThreshold(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder) { //2016 12 26 考虑 探探垂直上下方向滑动,不删除卡片,这里参照源码写死0.5f return recyclerView.getWidth() * /*getSwipeThreshold(viewHolder)*/ 0.5f; } @Override public Boolean onMove(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder,RecyclerView.ViewHolder target) { //由于不支持滑动排序,所以不需要处理此方法 return false; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder,int direction) { //当view需要滑动的时候,会回调此方法 //但是这个方法只是告诉你View需要滑动,并不是对View和Adapter进行额外的操作,//所以,如果你需要实现滑动删除,那么需要在此方法中remove item等. //我们这里需要对滑动过后的View,进行恢复操作. viewHolder.itemView.setRotation(0);//恢复最后一次的旋转状态 if (mSwipeListener != null) { mSwipe@R_616_3475@nSwipeTo(viewHolder,0); } notifyListener(viewHolder.getAdapterPosition(),direction); } private void notifyListener(int position,int direction) { Log.w(tag,"onSwiped: " + position + " " + direction); if (mSwipeListener != null) { mSwipe@R_616_3475@nSwiped(position,direction); } } @Override public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) { //滑动的比例达到多少之后,视为滑动 return 0.3f; } @Override public void onChildDraw(Canvas c,RecyclerView recyclerView,float dX,float dY,int actionState,Boolean isCurrentlyActivE) { super.onChildDraw(c,recyclerView,viewHolder,dX,dY,actionState,isCurrentlyActivE); //当你在滑动的过程中,此方法一直会被回调,就跟onTouch事件一样... //先根据滑动的dx dy 算出现在动画的比例系数fraction float swipeValue = (float) Math.sqrt(dX * dX + dY * dY); final float threshold = getThreshold(recyclerView,viewHolder); float fraction = swipeValue / threshold; //边界修正 最大为1 if (fraction > 1) { fraction = 1; } else if (fraction < -1) { fraction = -1; } //对每个ChildView进行缩放 位移 int childCount = recyclerView.getChildCount(); for (int i = 0; i < childCount; i++) { View child = recyclerView.getChildAt(i); //第几层,举例子,count =7, 最后一个TopView(6)是第0层, int level = childCount - i - 1; if (level > 0) { child.setScaleX(1 - SCALE_GAP * level + fraction * SCALE_GAp); if (level < MAX_SHOW_COUNT - 1) { child.setScaleY(1 - SCALE_GAP * level + fraction * SCALE_GAp); child.setTranslationY(TRANS_Y_GAP * level - fraction * TRANS_Y_GAp); } else { //child.setTranslationY((float) (mTranslationYGap * (level - 1) - fraction * mTranslationYGap)); } } else { //最上层 //rotate if (dX < -50) { child.setRotation(-fraction * MAX_ROTATION); } else if (dX > 50) { child.setRotation(fraction * MAX_ROTATION); } else { child.setRotation(0); } if (mSwipeListener != null) { RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int adapterPosition = params.getViewAdapterPosition(); mSwipe@R_616_3475@nSwipeTo(recyclerView.findViewHolderForAdapterPosition(adapterPosition),dX); } } } } //扩展实现:点击按钮实现左滑效果 public void toLeft(RecyclerView recyclerView) { if (check(recyclerView)) { animTo(recyclerView,falsE); } } //扩展实现:点击按钮实现右滑效果 public void toRight(RecyclerView recyclerView) { if (check(recyclerView)) { animTo(recyclerView,truE); } } private void animTo(final RecyclerView recyclerView,Boolean right) { final int position = recyclerView.getAdapter().getItemCount() - 1; final View view = recyclerView.findViewHolderForAdapterPosition(position).itemView; TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,Animation.RELATIVE_TO_SELF,right ? 1f : -1f,0f,1.3f); translateAnimation.setFillAfter(true); translateAnimation.setDuration(300); translateAnimation.seTinterpolator(new DecelerateInterpolator()); translateAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { isSwipeAnim = false; recyclerView.removeView(view); notifyListener(position,x > view.getMeasuredWidth() / 2 ? itemtouchhelper.RIGHT : itemtouchhelper.LEFT); } @Override public void onAnimationRepeat(Animation animation) { } }); view.startAnimation(translateAnimation); } private Boolean check(RecyclerView recyclerView) { if (isSwipeAnim) { return false; } if (recyclerView == null || recyclerView.getAdapter() == null) { return false; } if (recyclerView.getAdapter().getItemCount() == 0) { return false; } isSwipeAnim = true; return true; } public interface OnSwipeListener { /** * @param direction {@link itemtouchhelper#LEFT} / {@link itemtouchhelper#RIGHT} * {@link itemtouchhelper#UP} or {@link itemtouchhelper#DOWN}). */ void onSwiped(int adapterPosition,int direction); /** * 最上层View滑动时回调. * * @param viewHolder 最上层的ViewHolder * @param offset 距离原始位置的偏移量 */ void onSwipeTo(RecyclerView.ViewHolder viewHolder,float offset); } public static class SimpleSwipeCallBACk implements OnSwipeListener { /** * {@inheritDoc} */ @Override public void onSwiped(int adapterPosition,int direction) { } /** * {@inheritDoc} */ @Override public void onSwipeTo(RecyclerView.ViewHolder viewHolder,float offset) { } } }
看起来不难,但是真正做的时候,要处理的地方很多,
总之,做了你才会发现1+1=2的魅力,just do it.
开源地址: https://github.com/angcyo/RecyclerLayoutManager
好了,以上所示是小编给大家分享的Android开发中RecyclerView模仿探探左右滑动布局功能,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言。
以上是大佬教程为你收集整理的Android开发中RecyclerView模仿探探左右滑动布局功能全部内容,希望文章能够帮你解决Android开发中RecyclerView模仿探探左右滑动布局功能所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。