gpt4 book ai didi

android - View 之间尴尬的触摸事件传播

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:13:11 24 4
gpt4 key购买 nike

我有一个充满 ImageViewGallery,并且 ImageView 是双指缩​​放和可翻译的。我的目标是,一旦 ImageView 无法再向左/右移动,Gallery 就会滚动。所以有时 ImageView 需要处理触摸事件,有时 Gallery 需要处理触摸事件。我在我的 ImageViewonTouchEvent 方法中有逻辑用于何时发生切换,但我得到了意想不到的结果。我将在展示我的代码后解释问题:

// 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;
}

这是我的图库。我重写了 onTouchEvent 只是为了显示它何时接收到触摸事件。

// SwipeGallery.java

@Override
public boolean onTouchEvent( MotionEvent event ) {

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

因此,当我加载 Activity 时,我尝试从右向左滑动。立即触发传递运动事件的逻辑,但这是我的日志输出。

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.

第二次我从右向左滑动时,我得到了这个:

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 总是处理第一个运动事件,画廊总是处理第二个运动事件”的模式永远持续下去(为画廊中的每个位置创建一个新的 ImageView ,这就是为什么 isPassThroughTouchEvent() 在第 3 次、第 5 次等时返回 false)。那么我到底错过了什么?我认为返回 false 会传播触摸事件直到它被处理,但是 Gallery 不会在第一次接受它,但它会在第二次?这对我来说毫无意义。有人有想法么?谢谢。

最佳答案

当 View 在按下 (ACTION_DOWN) 运动事件时返回真值时,该 View 将“锁定”为触摸运动目标。这意味着它将接收后续的运动事件,直到最终的向上事件,而不管它发生在屏幕上的什么位置(参见 thread ),除非它的父级 wants 。和 allowed拦截事件。

解释你的情况:

  1. 在第一次滑动时,您的 ImageView 处理了使其成为运动目标的向下运动(请参阅日志)。这意味着所有后续运动事件都将传递给它,并且由于您的 Gallery 不会拦截事件,因此不会调用其 onTouchEvent 处理程序。

    <
  2. 在第二次滑动时,您的 ImageView 不处理向下运动(在日志中显示为“IM GETTING TOUCH!”+“IM RETURNING FALSE!”)并通过了事件传递给下一个处理程序,在本例中为 Gallery,它将运行其 onTouchEvent 处理程序。默认情况下,Gallery 始终处理向下事件,这会将其锁定为运动目标。

关于android - View 之间尴尬的触摸事件传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6914592/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com