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);
原文地址:https://www.cnblogs.com/liyanli-mu640065/p/9112311.html