zoukankan      html  css  js  c++  java
  • RecycleView 使用自定义CardLayouManager内容无法滚动问题

    1.开始一直反应不过来一个问题:RecycleView不是自带滚动效果吗?为啥子条目还不能全部滚动,显示出来呢?

    意识到:只有当RecycleView 适配器中条目数量特别多,才可以滚动。

    然而自己的布局,只是一个TextView内容特别多。

    2.所以网上看到看到下面的帖子里面的布局。自己修改后,完成。

    https://stackoverflow.com/questions/43753083/recycleview-using-view-holder-able-to-scroll-inside

     <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical" android:layout_width="match_parent"
            android:layout_height="match_parent">
            <android.support.v4.widget.NestedScrollView
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
        <android.support.v4.widget.SwipeRefreshLayout
                android:id="@+id/swipe_refresh_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    
        <android.support.v7.widget.RecyclerView
                    android:id="@+id/recycler_view"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:clipToPadding="false"
                    android:scrollbarStyle="outsideOverlay"
                    android:paddingBottom="28dp" />
            </android.support.v4.widget.SwipeRefreshLayout>
    
         </android.support.v4.widget.NestedScrollView>
    
    </LinearLayout>

     二、存在的问题:记得是:左右滑动加上后,就无法上下滚动了。

    后来切换了,采用的

    public class GallerySnapHelper extends SnapHelper {
        private static final float INVALID_DISTANCE = 1f;
        private static final float MILLISECONDS_PER_INCH = 40f;
        private OrientationHelper mHorizontalHelper;
        private RecyclerView mRecyclerView;
    
        private OnSwipeListener mListener;
    
        public OnSwipeListener getmListener() {
            return mListener;
        }
    
        public void setmListener(OnSwipeListener mListener) {
            this.mListener = mListener;
        }
    
    
    
        @Override
        public void attachToRecyclerView(@Nullable RecyclerView recyclerView) throws IllegalStateException {
            mRecyclerView = recyclerView;
            super.attachToRecyclerView(recyclerView);
        }
    
        @Override
        public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) {
            int[] out = new int[2];
            if (layoutManager.canScrollHorizontally()) {
                out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
            } else {
                out[0] = 0;
            }
            return out;
        }
    
        private int distanceToStart(View targetView, OrientationHelper helper) {
            return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
        }
    
        @Nullable
        protected LinearSmoothScroller createSnapScroller(final RecyclerView.LayoutManager layoutManager) {
            if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
                return null;
            }
            return new LinearSmoothScroller(mRecyclerView.getContext()) {
                @Override
                protected void onTargetFound(View targetView, RecyclerView.State state, Action action) {
                    int[] snapDistances = calculateDistanceToFinalSnap(mRecyclerView.getLayoutManager(), targetView);
                    final int dx = snapDistances[0];
                    final int dy = snapDistances[1];
                    final int time = calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy)));
                    if (time > 0) {
                        action.update(dx, dy, time, mDecelerateInterpolator);
                    }
                }
    
                @Override
                protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                    return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
                }
            };
        }
    
        @Override
        public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
            LogUtil.d(MainActivity.TAG,"---velocityX:::"+velocityX+"----velocityY:::"+velocityY);
            if(velocityX>0) {
                if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
                    LogUtil.d(MainActivity.TAG, "-!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)---RecyclerView.NO_POSITION--");
                    return RecyclerView.NO_POSITION;
                }
    
                final int itemCount = layoutManager.getItemCount();
                if (itemCount == 0) {
                    LogUtil.d(MainActivity.TAG, "-itemCount=0---RecyclerView.NO_POSITION--");
                    return RecyclerView.NO_POSITION;
                }
    
                final View currentView = findSnapView(layoutManager);
                if (currentView == null) {
                    LogUtil.d(MainActivity.TAG, "-currentView = null---RecyclerView.NO_POSITION--");
                    return RecyclerView.NO_POSITION;
                }
    
                final int currentPosition = layoutManager.getPosition(currentView);
                if (currentPosition == RecyclerView.NO_POSITION) {
                    LogUtil.d(MainActivity.TAG, "-currentPosition = RecyclerView.NO_POSITION---RecyclerView.NO_POSITION--");
                    return RecyclerView.NO_POSITION;
                }
    
                RecyclerView.SmoothScroller.ScrollVectorProvider vectorProvider =
                        (RecyclerView.SmoothScroller.ScrollVectorProvider) layoutManager;
                // deltaJumps sign comes from the velocity which may not match the order of children in
                // the LayoutManager. To overcome this, we ask for a vector from the LayoutManager to
                // get the direction.
                PointF vectorForEnd = vectorProvider.computeScrollVectorForPosition(itemCount - 1);
                if (vectorForEnd == null) {
                    LogUtil.d(MainActivity.TAG, "-vectorForEnd = null---RecyclerView.NO_POSITION--");
                    // cannot get a vector for the given position.
                    return RecyclerView.NO_POSITION;
                }
    
                //在松手之后,列表最多只能滚多一屏的item数
                int deltaThreshold = layoutManager.getWidth() / getHorizontalHelper(layoutManager).getDecoratedMeasurement(currentView);
    
                int hDeltaJump;
                if (layoutManager.canScrollHorizontally()) {
                    LogUtil.d(MainActivity.TAG, "----layoutManager.canScrollHorizontally()-----" + layoutManager.canScrollHorizontally());
                    hDeltaJump = estimateNextPositionDiffForFling(layoutManager,
                            getHorizontalHelper(layoutManager), velocityX, 0);
    
                    if (hDeltaJump > deltaThreshold) {
                        hDeltaJump = deltaThreshold;
                    }
                    if (hDeltaJump < -deltaThreshold) {
                        hDeltaJump = -deltaThreshold;
                    }
    
                    if (vectorForEnd.x < 0) {
                        hDeltaJump = -hDeltaJump;
                    }
                } else {
                    Log.d(TAG, "----hDeltaJump = 0--layoutManager.canScrollHorizontally()---" + layoutManager.canScrollHorizontally());
                    hDeltaJump = 0;
                }
    
                if (mListener != null) {
                    mListener.onSwipedClear();
                }
    
                if (hDeltaJump == 0) {
                    Log.d(TAG, "----if (hDeltaJump == 0)---true--");
                    return RecyclerView.NO_POSITION;
                }
    
                int targetPos = currentPosition + hDeltaJump;
                if (targetPos < 0) {
                    targetPos = 0;
                }
                if (targetPos >= itemCount) {
                    targetPos = itemCount - 1;
                }
                Log.d(TAG, "----targetPos-----" + targetPos);
                return targetPos;
            }else {
                //当判断是右滑时,不处理。
                Log.d(TAG, "-----“-1”-----");
                return -1;
            }
        }
    
        @Override
        public View findSnapView(RecyclerView.LayoutManager layoutManager) {
            return findStartView(layoutManager, getHorizontalHelper(layoutManager));
        }
    
    
        private View findStartView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
            if (layoutManager instanceof LinearLayoutManager) {
    
                LogUtil.d(MainActivity.TAG, "-findStartView---layoutManager instanceof LinearLayoutManager--");
                int firstChildPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
                if (firstChildPosition == RecyclerView.NO_POSITION) {
                    LogUtil.d(MainActivity.TAG, "-findStartView---firstChildPosition == RecyclerView.NO_POSITION--");
                    return null;
                }
    
                /*
                注释该段代码,否则不能正常滑动
                if (((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition() == layoutManager.getItemCount() - 1) {
                ///0
                    LogUtil.d(MainActivity.TAG, "-findStartView---layoutManager.getItemCount() - 1::::"+(layoutManager.getItemCount() - 1));
                    LogUtil.d(MainActivity.TAG, "-findStartView---((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition() == layoutManager.getItemCount() - 1--");
                    return null;
                }*/
    
                View firstChildView = layoutManager.findViewByPosition(firstChildPosition);
                if (helper.getDecoratedEnd(firstChildView) >= helper.getDecoratedMeasurement(firstChildView) / 2 && helper.getDecoratedEnd(firstChildView) > 0) {
                    return firstChildView;
                } else {
                    return layoutManager.findViewByPosition(firstChildPosition + 1);
                }
            } else {
                LogUtil.d(MainActivity.TAG, "-findStartView--!!!!!--layoutManager instanceof LinearLayoutManager--");
                return null;
            }
        }
    
    
        private int estimateNextPositionDiffForFling(RecyclerView.LayoutManager layoutManager,
                                                     OrientationHelper helper, int velocityX, int velocityY) {
            int[] distances = calculateScrollDistance(velocityX, velocityY);
            float distancePerChild = computeDistancePerChild(layoutManager, helper);
            if (distancePerChild <= 0) {
                return 0;
            }
            int distance = distances[0];
            if (distance > 0) {
                return (int) Math.floor(distance / distancePerChild);
            } else {
                return (int) Math.ceil(distance / distancePerChild);
            }
        }
    
        private float computeDistancePerChild(RecyclerView.LayoutManager layoutManager,
                                              OrientationHelper helper) {
            View minPosView = null;
            View maxPosView = null;
            int minPos = Integer.MAX_VALUE;
            int maxPos = Integer.MIN_VALUE;
            int childCount = layoutManager.getChildCount();
            if (childCount == 0) {
                return INVALID_DISTANCE;
            }
    
            for (int i = 0; i < childCount; i++) {
                View child = layoutManager.getChildAt(i);
                final int pos = layoutManager.getPosition(child);
                if (pos == RecyclerView.NO_POSITION) {
                    continue;
                }
                if (pos < minPos) {
                    minPos = pos;
                    minPosView = child;
                }
                if (pos > maxPos) {
                    maxPos = pos;
                    maxPosView = child;
                }
            }
            if (minPosView == null || maxPosView == null) {
                return INVALID_DISTANCE;
            }
            int start = Math.min(helper.getDecoratedStart(minPosView),
                    helper.getDecoratedStart(maxPosView));
            int end = Math.max(helper.getDecoratedEnd(minPosView),
                    helper.getDecoratedEnd(maxPosView));
            int distance = end - start;
            if (distance == 0) {
                return INVALID_DISTANCE;
            }
            return 1f * distance / ((maxPos - minPos) + 1);
        }
    
    
        private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) {
            if (mHorizontalHelper == null) {
                mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
            }
            return mHorizontalHelper;
        }
    
    }
    public interface OnSwipeListener<T>{
        /**
         * 卡片还在滑动时回调
         *
         * @param viewHolder 该滑动卡片的viewHolder
         * @param ratio      滑动进度的比例
         * @param direction  卡片滑动的方向,CardConfig.SWIPING_LEFT 为向左滑,CardConfig.SWIPING_RIGHT 为向右滑,
         *                   CardConfig.SWIPING_NONE 为不偏左也不偏右
         */
        void onSwiping(RecyclerView.ViewHolder viewHolder, float ratio, int direction);
    
        /**
         * 卡片完全滑出时回调
         *
         * @param viewHolder 该滑出卡片的viewHolder
         * @param t          该滑出卡片的数据
         * @param direction  卡片滑出的方向,CardConfig.SWIPED_LEFT 为左边滑出;CardConfig.SWIPED_RIGHT 为右边滑出
         */
        void onSwiped(RecyclerView.ViewHolder viewHolder, T t, int direction);
    
        /**
         * 所有的卡片全部滑出时回调
         */
        void onSwipedClear();
    
    }
    Activity 界面代码
    GallerySnapHelper mGallerySnapHelper = new GallerySnapHelper(); mGallerySnapHelper.setmListener(new OnSwipeListener() { @Override public void onSwiping(RecyclerView.ViewHolder viewHolder, float ratio, int direction) { } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, Object o, int direction) { } @Override public void onSwipedClear() { Log.d(TAG,"-----onSwipedClear----"); giRecyclerView.postDelayed(new Runnable() { @Override public void run() { groupIdeaHttp.getJtidea(URLCODE_GET_GROUP_IDEA,oaapi.getBASE_URL3()); giRecyclerView.getAdapter().notifyDataSetChanged(); } }, 100L); } }); mGallerySnapHelper.attachToRecyclerView(giRecyclerView); giRecyclerView.setAdapter(groupIdeaAdapter);
  • 相关阅读:
    ActiveMQ 5.15.12(2020年3月9日)
    Vert.x WebClient WebClientOptions
    第三方App接入微信登录
    Android Sutdio自带的代码检查工具analyze的使用
    WIN7系统有些文本乱码怎么办
    Visual Studio 打开程序提示仅我的代码怎么办
    WIN10平板 总是提示你需要管理员权限怎么办
    WIN10平板 如何修改网络IP地址为固定
    WIN10平板 如何设置不允许切换竖屏
    WIN10平板 如何关闭自动更新
  • 原文地址:https://www.cnblogs.com/liyanli-mu640065/p/9112311.html
Copyright © 2011-2022 走看看