当前位置: 代码迷 >> Android >> Android:垂直Recyclerview内的Horizo??ntal Recyclerview
  详细解决方案

Android:垂直Recyclerview内的Horizo??ntal Recyclerview

热度:116   发布时间:2023-08-04 10:50:11.0

这似乎是android中相当普遍的模式。 我正在尝试创建类似Facebook显示广告的方式:

您可以看到它们具有外部垂直回收视图,内部水平回收视图作为外部垂直recyclerview适配器中的项目之一。

我按照Google的指南“在ViewGroup中管理触摸事件” - 因为Recyclerview扩展了ViewGroup,其代码类似于我想要做的。

我对它进行了一些定制,以便检测Y轴的移动而不是X轴的移动,并将其应用到外部垂直再循环视图。

/**
 * Created by Simon on 10/11/2015.
 *///This is the recyclerview that would allow all vertical scrolls
public class VerticallyScrollRecyclerView extends RecyclerView {


    public VerticallyScrollRecyclerView(Context context) {
        super(context);
    }

    public VerticallyScrollRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public VerticallyScrollRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }


    ViewConfiguration vc = ViewConfiguration.get(this.getContext());
    private int mTouchSlop = vc.getScaledTouchSlop();
    private boolean mIsScrolling;
    private float startY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = MotionEventCompat.getActionMasked(ev);
        // Always handle the case of the touch gesture being complete.
        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            // Release the scroll.
            mIsScrolling = false;
            startY = ev.getY();
            return false; // Do not intercept touch event, let the child handle it
        }
        switch (action) {
            case MotionEvent.ACTION_MOVE: {
                if (mIsScrolling) {
                    // We're currently scrolling, so yes, intercept the
                    // touch event!
                    return true;
                }

                // If the user has dragged her finger horizontally more than
                // the touch slop, start the scroll

                // left as an exercise for the reader
                final float yDiff = calculateDistanceY(ev.getY());
                Log.e("yDiff ", ""+yDiff);
                // Touch slop should be calculated using ViewConfiguration
                // constants.
                if (yDiff > mTouchSlop) {
                    // Start scrolling!
                    Log.e("Scroll", "we are scrolling vertically");
                    mIsScrolling = true;
                    return true;
                }
                break;
            }
        }
        return false;
    }

    private float calculateDistanceY(float endY) {
        return startY - endY;
    }

}

我的xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/main_recyclerview_holder">

    <com.example.simon.customshapes.VerticallyScrollRecyclerView
        android:id="@+id/main_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
/>

</RelativeLayout>

当我尝试拖动内部水平回收视图时(希望touchevent被外部垂直回收视图拦截),外部回收视图根本不会垂直滚动。

它也给我一个错误说:

处理滚动时出错; 未找到id -1的指针索引。 是否跳过任何??MotionEvents?

有谁知道如何正常工作?

我有类似的问题,并没有在网上找到任何解决方案。 在我的应用程序中,我有自定义交互元素的列表,您可以使用它与水平滑动交互(在这种情况下,应该锁定滚动),但是当您垂直滑动时,它应该滚动。 根据你的评论,你已经解决了你的问题,但是对于那些问题与我的问题类似并且研究领导他们的人,我会发布我的解决方案。 我看起来有点在RecyclerView的引擎盖下,这就是我发现的。 “处理滚动时出错;找不到id -1的指针索引。是否跳过了任何MotionEvents?” - 问题是当ACTION_DOWN发生时,用于获取index的变量mScrollPointerIdonTouchEvent设置。在我的特殊情况下,当ACTION_DOWN发生时,我从onInterceptTouchEvent返回false ,因为那时我不知道天气用户想要滚动或与列表元素交互。 在这种情况下,不会调用onTouchEvent 稍后,当我发现用户想要与元素onInterceptTouchEvent ,我从onInterceptTouchEvent返回false并onTouchEvent ,但它无法处理滚动,因为未设置mScrollPointerId 这里的解决方案是在ACTION_DOWN发生时从onInterceptTouchEvent调用onTouchEvent

@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
    ...
    switch (action) {
        case MotionEvent.ACTION_DOWN: {
            onTouchEvent(e);
            ...
            break;
            }
        ...
        }
    ...
}
  相关解决方案