2

NestedScrollView と @Override のメソッドを拡張します: onTouchEventonInterceptTouchEvent。問題は、super.onTouchEvent が ACTION_DOWN を呼び出さないことです (onIntereceptTouchEvent によって呼び出されます)。そのため、NestedScrollView が移動せず、エラーが発生します。

onTouchEvent の無効な pointerId=-1

ACTION_DOWN がトリガーされると、NestedScrollView の onTouchEvent メソッドでポインター ID が設定されます。

mActivePointerId = MotionEventCompat.getPointerId(ev, 0);

これを自分で設定することはできません。onTouchEvent メソッド全体を書き直すのは面倒な計画のようです。ここでヘルプを使用できます。タッチ イベントをリッスンしない View をクリックすると、NestedScrollView が移動します (基本的に、onInterecptTouchEvent メソッドは呼び出されず、ACTION_DOWN は NestedScrollView onTouchEvent で処理されます)。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    Log.i(LOGTAG, String.valueOf(ev.getAction()));

    final int action = MotionEventCompat.getActionMasked(ev);

    if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
        mIsBeingDragged = false;
        Log.i(LOGTAG, "is scrolling" + String.valueOf(mIsBeingDragged));
        return false; // Do not intercept touch event, let the child handle it
    }

    switch (action) {
        case MotionEvent.ACTION_DOWN: {
            mStartY = ev.getY();
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            if (mIsBeingDragged) {
                return true;
            }

            final int yDiff = calculateDistanceY(ev);
            Log.d(LOGTAG, "y difference: y");
            if (yDiff > mTouchSlop) {
                mIsBeingDragged = true;
                return true;
            }
            break;
        }
    }
    return false;
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    Log.i(LOGTAG, "onTouchEvent");
    if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) {
        mIsBeingDragged = false;
    }

    return super.onTouchEvent(ev);
}
4

1 に答える 1

5

以下は私の問題を修正したコードです、私はうそをつく必要がありました:

@Override
public boolean onTouchEvent(MotionEvent ev) {
    Log.i(LOGTAG, "onTouchEvent");
    if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) {
        mIsBeingDragged = true;
    }

    if (mFirstOnTouchEvent) {
        ev.setAction(MotionEvent.ACTION_DOWN);
        ev.setLocation(mStartX, mStartY);
        mFirstOnTouchEvent = false;
    }

    return super.onTouchEvent(ev);
}

onInterceptTouchEvent で ACTION_DOWN がトリガーされたときに、mFirstOnTouchEvent を true に設定します。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
  if (MotionEventCompat.getActionMasked(ev) == MotionEvent.ACTION_DOWN) {
    mFirstOnTouchEvent = true
  }

  ...
}
于 2015-09-22T06:12:15.437 に答える