android - 当用户在水平回收器 View 上滑动时停止垂直移动

标签 android android-recyclerview

我在运动布局中有一个水平回收器 View 。有时,当我进行水平滑动时,页面开始沿垂直方向滚动。当我们进行对角线 throw 时,就会发生这种情况。

我想要像 Google Play 这样的东西,其中水平回收器 View 可以防御稍微对角的垂直滑动。顺便说一句,设置 nestedscrollEnabled 不起作用。

最佳答案

有一篇关于所有 RecycleView 滚动行为和问题本身的很好的文章。查看鲁本·索萨 article 。解决方案很简单,尝试使用采用的RecyclerView:

/**
 * A RecyclerView that only handles scroll events with the same orientation of its LayoutManager.
 * Avoids situations where nested recyclerviews don't receive touch events properly:
 */
public class OrientationAwareRecyclerView extends RecyclerView {

    private float lastX = 0.0f;
    private float lastY = 0.0f;
    private boolean scrolling = false;

    public OrientationAwareRecyclerView(@NonNull Context context) {
        this(context, null);
    }

    public OrientationAwareRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public OrientationAwareRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs,
                                        int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        addOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                scrolling = newState != RecyclerView.SCROLL_STATE_IDLE;
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        final LayoutManager lm = getLayoutManager();
        if (lm == null) {
            return super.onInterceptTouchEvent(e);
        }

        boolean allowScroll = true;

        switch (e.getActionMasked()) {
            case MotionEvent.ACTION_DOWN: {
                lastX = e.getX();
                lastY = e.getY();
                // If we were scrolling, stop now by faking a touch release
                if (scrolling) {
                    MotionEvent newEvent = MotionEvent.obtain(e);
                    newEvent.setAction(MotionEvent.ACTION_UP);
                    return super.onInterceptTouchEvent(newEvent);
                }
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                // We're moving, so check if we're trying
                // to scroll vertically or horizontally so we don't intercept the wrong event.
                float currentX = e.getX();
                float currentY = e.getY();
                float dx = Math.abs(currentX - lastX);
                float dy = Math.abs(currentY - lastY);
                allowScroll = dy > dx ? lm.canScrollVertically() : lm.canScrollHorizontally();
                break;
            }
        }

        if (!allowScroll) {
            return false;
        }

        return super.onInterceptTouchEvent(e);
    }
}

关于android - 当用户在水平回收器 View 上滑动时停止垂直移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57853641/

相关文章:

android - 单击时 RecyclerView 项目的 X 和 Y 为 0

android - 在哪里存储可以被任何android Activity 使用的jsonArray?

Android:更改其他应用程序的优先级

android - 广播接收器中的Android音频管理器

android - SuperSlim 不适用于 Android 支持库 23.2.1

android - 将 recyclerview 项目限制为仅 10 个而不使用过滤器分页

android - Android L 中的 RecyclerView ItemAnimator 故障

android - cordova fs.root.getDirectory 在三星安卓手机上失败(PATH_EXISTS_ERR)

javascript - 图片的高度与手机/平板电脑的高度相同 - 只能在 Chrome 中正常工作

android - 在 android recyclerview 中一次仅捕捉一项,而不捕捉更多项目