ScrollView和RecycleView滑动冲突

本文介绍了解决ScrollView与RecyclerView组合使用时出现的滑动冲突问题,并提供了一个有效的方法来确保滑动流畅,同时避免了数据展示不全的情况。

今天在ScrollView和RecycleView组合使用的过程中,recycleView在有些机型上面出现滑动冲突,RecycleView item只出现一条数据

解决方案
重写RecycleView空间,重写其中的onMeasure方法

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,

                MeasureSpec.AT_MOST);

        super.onMeasure(widthMeasureSpec, expandSpec);
    }
使得RcycleView适应ScrollView的滑动。

 

滑动冲突已经解决,但是接下来在华为荣耀note8上面出现滑动卡顿,然后禁掉RecycleView滑动,完美解决


 //禁止recycleView垂直方向滑动
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this){
        @Override
        public boolean canScrollVertically() {
            return false;
        }
    };  

rcShowAd.setLayoutManager(linearLayoutManager);




在 Android 开发中,ScrollView 嵌套 RecyclerView 时经常遇到滑动冲突的问题,这主要是由于两者都具备垂直滚动能力。为了解决这个问题,可以通过以下几种方法来实现滑动冲突的处理: ### 方法一:禁止 RecyclerView 滑动 最直接的解决方案是通过自定义 `LinearLayoutManager` 或 `GridLayoutManager` 来禁用 RecyclerView 的垂直滑动能力。这种方式适用于 RecyclerView 的内容高度固定且不需要滚动的情况。 ```java LinearLayoutManager layoutManager = new LinearLayoutManager(this) { @Override public boolean canScrollVertically() { // 直接禁止垂直滑动 return false; } }; ``` 通过这种方式,RecyclerView 将无法滚动,而外部的 ScrollView 可以正常滚动,从而避免冲突[^2]。 ### 方法二:动态调整 RecyclerView滚动能力 如果 RecyclerView 的内容高度不固定,或者需要根据某些条件动态控制是否允许 RecyclerView 滚动,可以自定义一个 `GridLayoutManager` 并添加一个开关来控制是否允许垂直滑动。 ```java public class ScrollGridViewLayoutManager extends GridLayoutManager { private boolean isScrollEnable = true; public ScrollGridViewLayoutManager(Context context, int spanCount) { super(context, spanCount); } public ScrollGridViewLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { super(context, spanCount, orientation, reverseLayout); } @Override public boolean canScrollVertically() { return isScrollEnable && super.canScrollVertically(); } /** * 设置 RecyclerView 是否可以垂直滑动 * @param isEnable */ public void setScrollEnable(boolean isEnable) { this.isScrollEnable = isEnable; } } ``` 通过调用 `setScrollEnable()` 方法,可以在运行时动态控制 RecyclerView 是否允许滚动[^3]。 ### 方法三:自定义 ScrollView 处理滑动事件 另一种方法是通过自定义 ScrollView,重写其 `onInterceptTouchEvent()` `onTouchEvent()` 方法,以更精细地控制滑动事件的分发。这种方法适用于需要更复杂的滑动行为控制的场景。 ```java public class FScrollView extends ScrollView { private float mLastXIntercept = 0f; private float mLastYIntercept = 0f; public FScrollView(Context context) { super(context); } public FScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public FScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mLastXIntercept = ev.getX(); mLastYIntercept = ev.getY(); break; case MotionEvent.ACTION_MOVE: float curX = ev.getX(); float curY = ev.getY(); if (Math.abs(curY - mLastYIntercept) > Math.abs(curX - mLastXIntercept)) { // 垂直滑动,拦截事件 return true; } break; } return super.onInterceptTouchEvent(ev); } } ``` 通过这种方式,ScrollView 可以根据用户的滑动方向决定是否拦截事件,从而更好地 RecyclerView 协作[^4]。 ### 方法四:使用 NestedScrollView 替代 ScrollView Android 官方推荐使用 `NestedScrollView` 替代 ScrollView,因为它支持 RecyclerView 的嵌套滚动行为。通过将 ScrollView 替换为 NestedScrollView,并结合 `AppBarLayout` 或其他支持嵌套滚动的组件,可以更优雅地处理滑动冲突。 ```xml <androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 其他视图 --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </androidx.core.widget.NestedScrollView> ``` 使用 `NestedScrollView` 可以自动处理嵌套滚动行为,避免手动干预滑动冲突[^1]。 ### 方法五:设置 RecyclerView 的高度 如果 RecyclerView 的内容高度是固定的,可以通过动态计算 RecyclerView 的高度并设置其 `layoutParams` 来避免滑动冲突。这种方法适用于 RecyclerView 内容较少且不需要滚动的情况。 ```java public static void setRecyclerViewHeightBasedOnChildren(RecyclerView recyclerView) { RecyclerView.Adapter adapter = recyclerView.getAdapter(); if (adapter == null) { return; } int totalHeight = 0; for (int i = 0; i < adapter.getItemCount(); i++) { View item = adapter.createViewHolder(recyclerView, adapter.getItemViewType(i)).itemView; item.measure(0, 0); totalHeight += item.getMeasuredHeight(); } RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); if (layoutManager instanceof LinearLayoutManager) { int padding = recyclerView.getPaddingTop() + recyclerView.getPaddingBottom(); recyclerView.getLayoutParams().height = totalHeight + padding; recyclerView.requestLayout(); } } ``` 通过这种方式,RecyclerView 的高度会被设置为所有子项的高度总,从而避免滚动冲突[^1]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值