Android 接收ViewGroup中的interceptTouchEvent

Android 接收ViewGroup中的interceptTouchEvent,android,Android,我已经构建了一个自定义视图组,如 public class InterceptorView extends ViewGroup { public InterceptorView(Context context) { super(context); } public InterceptorView(Context context, AttributeSet attrs) { super(context, attrs); }

我已经构建了一个自定义视图组,如

public class InterceptorView extends ViewGroup {

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

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

    public InterceptorView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        View view = getChildAt(0);
        view.layout(l, t, r, b);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d(InterceptorView.class.getCanonicalName(), "y: " + ev.getY());
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wspec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
        int hspec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = getChildAt(i);
            view.measure(wspec, hspec);
        }
    }
}
公共类拦截器视图扩展了视图组{
公共拦截器视图(上下文){
超级(上下文);
}
公共拦截器视图(上下文、属性集属性){
超级(上下文,attrs);
}
公共拦截器视图(上下文、属性集属性、int-defStyleAttr){
super(上下文、attrs、defStyleAttr);
}
@凌驾
仅受保护的void布局(布尔值已更改、int l、int t、int r、int b){
视图=getChildAt(0);
视图。布局图(l、t、r、b);
}
@凌驾
公共布尔值onInterceptTouchEvent(MotionEvent ev){
Log.d(InterceptorView.class.getCanonicalName(),“y:+ev.getY());
返回超级onInterceptTouchEvent(ev);
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
超级测量(宽度测量、高度测量);
int wspec=MeasureSpec.makeMeasureSpec(getMeasuredWidth(),MeasureSpec.justice);
int hspec=MeasureSpec.makeMeasureSpec(getMeasuredHeight(),MeasureSpec.justice);
int childCount=getChildCount();
for(int i=0;i
并扩展了以下xml

<?xml version="1.0" encoding="utf-8"?>
<test.com.viewgroupexamples.InterceptorView xmlns:android="http://schemas.android.com/apk/res/android"
                                            android:orientation="vertical"
                                            android:layout_width="match_parent"
                                            android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/contentView"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </LinearLayout>
    </ScrollView>

</test.com.viewgroupexamples.InterceptorView>

我动态添加了100个文本视图,因此scrollview实际上可以滚动


通过这种设置,我希望interceptTouchEvent甚至可以记录发生的touchevent。不过,我通常会先下棋,再进行几次移动,然后就停止了。这是正确的行为还是我做错了什么?

您会注意到'onInterceptTouchEvent()'返回一个布尔值。这表示您对该事件感兴趣(该事件已被“截获”)。如果初始关闭事件未返回true,则后续事件将不会调用此方法。但是要小心,因为如果这样做,层次结构中较低的视图将不会接收这些事件。简而言之,更换

return super.onInterceptTouchEvent(ev);


因此,在ViewGroup中有一个名为RequestDisallowWinterCeptTouchEvent的方法。这将阻止返回当前手势的onInterceptTouchEvent。这意味着拦截器View.onInterceptTouchEvent()接收到DOWN事件,然后是几个移动事件,直到触控斜率被克服,然后Scrollview在接收到ontouch的MOVE in时实际调用RequestDisallowWinterCeptTouchEvent

我通过覆盖RequestDisallowWinterCeptTouchEvent方法克服了这个问题,如下所示

@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}

我认为你正在混淆onTouch()和onInterceptTouchEvent的行为。看看下面我的答案,让我知道你的想法是的,你是对的。。。。我实际上没有检查文档,只是从内存中写入。实际上,在“onInterceptTouchEvent”中返回true将导致调用ViewGroup的“onTouchEvent”来处理原始的关闭事件和后续事件。顺便说一句,这是你应该处理事件的地方,而不是在“onInterceptTouchEvent”中。话虽如此,您也可以使用'RequestDisallowWinterCeptTouchEvent',以获得'onInterceptTouchEvent'回调。
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}