6

私はsでGalleryいっぱいですImageView、そしてImageViewsはピンチズーム可能で翻訳可能です。私の目標は、ImageView缶が左右に翻訳できなくなると、Galleryがスクロールすることです。したがってImageView、タッチイベントを処理する必要がある場合もあれば、タッチイベントをGallery処理する必要がある場合もあります。ハンドオフを発生させたいときImageViewのメソッドにロジックがありますが、予期しない結果が得られます。onTouchEventコードを表示した後、問題について説明します。

// PinchZoomImageView.java

@Override
public boolean onTouchEvent( MotionEvent event ) {

    Log.i( "PinchZoomImageView", "IM GETTING TOUCHED!" );

    if ( isPassThroughTouchEvent() ) {
        Log.i( "PinchZoomImageView", "IM RETURNING FALSE!" );
        return false;
    }

    getScaleDetector().onTouchEvent( event );

    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN: {
            final float x = event.getX();
            final float y = event.getY();

            setLastTouchX( x );
            setLastTouchY( y );
            setActivePointerId( event.getPointerId( 0 ) );

            break;
        }

        case MotionEvent.ACTION_MOVE: {
            final int pointerIndex = event.findPointerIndex( getActivePointerId() );
            final float x = event.getX( pointerIndex );
            final float y = event.getY( pointerIndex );

            // Only move if the ScaleGestureDetector isn't processing a gesture.
            if ( !getScaleDetector().isInProgress() ) {
                if ( isDetectMovementX() ) {
                    final float dx = x - getLastTouchX();
                    setPosX( getPosX() + dx );
                }

                if ( isDetectMovementY() ) {
                    final float dy = y - getLastTouchY();
                    setPosY( getPosY() + dy );
                }

                invalidate();
            }

            setLastTouchX( x );
            setLastTouchY( y );

            if ( isAtXBound() && !isPassThroughTouchEvent() ) {

                setPassThroughTouchEvent( true );
            }

            break;
        }

        case MotionEvent.ACTION_UP: {
            setActivePointerId( INVALID_POINTER_ID );
            break;
        }

        case MotionEvent.ACTION_CANCEL: {
            setActivePointerId( INVALID_POINTER_ID );
            break;
        }

        case MotionEvent.ACTION_POINTER_UP: {
            final int pointerIndex = ( event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK ) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = event.getPointerId( pointerIndex );
            if ( pointerId == getActivePointerId() ) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                setLastTouchX( event.getX( newPointerIndex ) );
                setLastTouchY( event.getY( newPointerIndex ) );
                setActivePointerId( event.getPointerId( newPointerIndex ) );
            }
            break;
        }
    }

    return true;
}

そして、これが私のGalleryです。onTouchEventタッチイベントを受信したときに表示するためだけに上書きしました。

// SwipeGallery.java

@Override
public boolean onTouchEvent( MotionEvent event ) {

    Log.i( "SwipeGallery", "IM GETTING TOUCHED!" );
    return super.onTouchEvent( event );
}

したがって、アクティビティをロードするときは、右から左にスワイプしようとします。モーションイベントをパススルーするロジックがすぐにトリガーされますが、これが私のログ出力です。

08-02 10:04:47.097: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.179: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.179: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.179: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.230: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.230: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.230: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.230: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.245: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.245: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.261: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.261: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.277: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.277: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.296: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.296: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.312: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.312: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.327: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.327: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.343: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.343: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:04:47.360: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:04:47.360: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
....etc.

右から左にスワイプした2回目は、次のようになります。

08-02 10:27:31.573: INFO/PinchZoomImageView(17189): IM GETTING TOUCHED!
08-02 10:27:31.573: INFO/PinchZoomImageView(17189): IM RETURNING FALSE!
08-02 10:27:31.573: INFO/SwipeGallery(17189): IM GETTING TOUCHED!
08-02 10:27:31.636: INFO/SwipeGallery(17189): IM GETTING TOUCHED!
08-02 10:27:31.636: INFO/SwipeGallery(17189): IM GETTING TOUCHED!
08-02 10:27:31.683: INFO/SwipeGallery(17189): IM GETTING TOUCHED!
08-02 10:27:31.933: INFO/SwipeGallery(17189): IM GETTING TOUCHED!
08-02 10:27:31.964: INFO/SwipeGallery(17189): IM GETTING TOUCHED!
08-02 10:27:31.999: INFO/SwipeGallery(17189): IM GETTING TOUCHED!
08-02 10:27:32.034: INFO/SwipeGallery(17189): IM GETTING TOUCHED!

この「imageviewが常に処理する1番目のモーションイベント、ギャラリーが常に処理する2番目のモーションイベント」のパターンは永遠に続きます(ギャラリー内の位置ごとに新しいimageviewが作成されるためisPassThroughTouchEvent()、3回目、5回目などでfalseが返されます)。それで、私はここで正確に何が欠けていますか?falseを返すと、タッチイベントが処理されるまで伝播すると思いましたがGallery、最初は取得しませんが、2回目は処理しますか?これは私には意味がありません。誰かアイデアはありますか?ありがとう。

4

1 に答える 1

3

ビューがダウン(ACTION_DOWN)モーションイベントでtrueを返すと、そのビューはタッチモーションターゲットとして「ロックイン」されます。つまり、親がイベントをインターセプトすることを望ん許可されている場合を除き、画面のどこで発生するかに関係なく、最後のアップイベントまでの後続のモーションイベントを受信します(このスレッドを参照)。

あなたの状況を説明するには:

  1. 最初のスワイプでImageView、モーションターゲットになるダウンモーションを処理しました(ログを参照)。つまり、後続のすべてのモーションイベントが配信されGallery、イベントをインターセプトしないため、onTouchEventハンドラーは呼び出されません。

  2. 2回目のスワイプで、ImageViewダウンモーションを処理せず(ログに「IMGETTING TOUCH!」+「IMRETURNING FALSE!」で表示)、イベントを次のハンドラーに渡します。この場合GalleryonTouchEventハンドラ。デフォルトでGalleryは、常にダウンイベントを処理します。これにより、モーションターゲットとしてロックインされます。

于 2011-08-05T14:28:56.320 に答える