androidstudio开发原生看书遇到的关于onTouchEvent()事件不响应的坑

这几天开发原生看书逻辑好乱,各种activity、flipviewcontroller、booksingleview的ontouch、onclick事件堆积,还被androidstudio坑了1天,晕死,把遇到问题的地方记录一下。

1、书中的视频进度条不能拖动,现在的情况是拖动进度条时直接翻到下一页,不能响应拖动进度条事件。

1.1可能是事件被FlipView直接拦截消费掉了,没有分发到下一层,

1.2查看FlipViewController中原有代码:

	@Override
	public boolean onInterceptTouchEvent(MotionEvent event) {

		if (flipByTouchEnabled) {
			return cards.handleTouchEvent(event, false);
		} else {
			return false;
		}
	}
1.3cards.handlerTouchEvent(…);代码如下:

public synchronized boolean handleTouchEvent(MotionEvent event, boolean isOnTouchEvent) {
        Log.i("","########handleTouchEvent " + event.getAction());
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastPageIndex = getPageIndexFromAngle(accumulatedAngle);
                lastPosition = orientationVertical ? event.getY() : event.getX();
                Log.i("","handleTouchEvent 走 down了吗");
                return isOnTouchEvent;
            case MotionEvent.ACTION_MOVE:
                float delta = orientationVertical ? (lastPosition - event.getY()) : (lastPosition - event.getX());

                if (Math.abs(delta) > controller.getTouchSlop()) {
                    setState(STATE_TOUCH);
                    forward = delta > 0;
                }
                if (state == STATE_TOUCH) {
                    if (Math.abs(delta) > MIN_MOVEMENT) // ignore small movements
                    {
                        forward = delta > 0;
                    }

                    controller.showFlipAnimation();

                    float angleDelta;
                    if (orientationVertical) {
                        angleDelta = 180 * delta / controller.getContentHeight() * MOVEMENT_RATE;
                    } else {
                        angleDelta = 180 * delta / controller.getContentWidth() * MOVEMENT_RATE;
                    }

                    if (Math.abs(angleDelta) > MAX_TOUCH_MOVE_ANGLE) {
                        angleDelta = Math.signum(angleDelta) * MAX_TOUCH_MOVE_ANGLE;
                    }

                    // do not flip more than one page with one touch...
                    if (Math.abs(getPageIndexFromAngle(accumulatedAngle + angleDelta) - lastPageIndex) <= 1) {
                        accumulatedAngle += angleDelta;
                    }

                    // Bounce the page for the first and the last page
                    if (frontCards.getIndex() == maxIndex - 1) { // the last page
                        if (accumulatedAngle > frontCards.getIndex() * 180) {
                            accumulatedAngle = Math.min(accumulatedAngle, controller.isOverFlipEnabled() ? (frontCards.getIndex() * 180 + MAX_TIP_ANGLE) : (frontCards.getIndex() * 180));
                        }
                    }

                    if (accumulatedAngle < 0) {
                        accumulatedAngle = Math.max(accumulatedAngle, controller.isOverFlipEnabled() ? -MAX_TIP_ANGLE : 0);
                    }

                    int anglePageIndex = getPageIndexFromAngle(accumulatedAngle);

                    if (accumulatedAngle >= 0) {


                        if (anglePageIndex != frontCards.getIndex()) {
                            if (anglePageIndex == frontCards.getIndex() - 1) { // moved
                                // to previous page
                                swapCards(); // frontCards becomes the backCards
                                frontCards.resetWithIndex(backCards.getIndex() - 1);
                                controller.flippedToView(anglePageIndex, false);
                            } else if (anglePageIndex == frontCards.getIndex() + 1) { // moved
                                // to next page
                                swapCards();
                                backCards.resetWithIndex(frontCards.getIndex() + 1);
                                controller.flippedToView(anglePageIndex, false);
                            } else {
                                throw new RuntimeException(AphidLog.format("Inconsistent states: anglePageIndex: %d, accumulatedAngle %.1f, frontCards %d, backCards %d", anglePageIndex, accumulatedAngle, frontCards.getIndex(), backCards.getIndex()));
                            }
                        }
                    }

                    lastPosition = orientationVertical ? event.getY() : event.getX();

                    controller.getSurfaceView().requestRender();

                    return true;
                }

                return isOnTouchEvent;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (state == STATE_TOUCH) {
                    if (accumulatedAngle < 0) {
                        forward = true;
                    } else if (accumulatedAngle >= frontCards.getIndex() * 180 && frontCards.getIndex() == maxIndex - 1) {
                        forward = false;
                    }

                    setState(STATE_AUTO_ROTATE);
                    controller.getSurfaceView().requestRender();
                }
                return isOnTouchEvent;
        }

        return false;
    }
1.4翻页时onInterceptTouchEvent直接执行cards.handleTouchEvent(event,true)这个函数,直接将手势拦截。

1.5虽然返回的是false,但是手势已进行处理,上层的imageview的ontouchevent()事件处理优先级不够。

1.6解决方案:不在onInterceptTouchEvent()方法中执行cards.handleTouchEvent()函数,直接返回false。(后来已将onInterceptTouchEvent方法去掉)

2、去掉onInterceptTouchEvent()之后seekbar已经可以拖动,轮播图也可以拖动到下一页,不会再直接flip到下一页。

2.1问题:但是点击到图片滑动时则无法滑动,onInterceptTouchEvent()没被删掉时可以滑动(FlipViewController的优先级别高),所以说图片应该抢占了并消费了滑动事件。

2.2去找imageview代码,发现展示图片时啥也没做,就设置了onclickListener,没设置onclickListener的图表图片就可以滑动。

2.3解决方案:自定义imageview,重写ontouchEvent()方法,保证既可以响应到click事件(单击图片时跳转到另一activity放大显示),又不消费滑动事件使flipview可以滑动。

3、自定义ImageView,重写onTouchEvent()方法,代码如下:

@Override
public boolean onTouchEvent(MotionEvent event) {
    
	Log.i("","ImageViewFlipInside onTouchEvent: " +event.getAction());
    
	 switch(event.getAction){
		case MotionEvent.ActionDown:
			Log.i(“”,”onTouchEvent ActionDown”);
		break;	
		case MotionEvent.ActionUp:
			Log.i(“”,”onTouchEvent ActionUp”);
		break;	
		case MotionEvent.ActionCancel:
			Log.i(“”,”onTouchEvent ActionCancel”);
		break;	
	}
    return super.onTouchEvent(event);
}
3.1发现AndroidStudio中完全不打印onTouchEvent中的log,一个都不打印,只有偶尔打印一次,或者整个手掌放到平板时才打印log

3.2难道是imageView和flipView中的其他层级抢占了事件?

3.3找了一下BookSingleActivity和BookSingleView中的一些可能会抢占的代码,

3.4BookSingleActivity中只有个 public boolean dispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); } 这个事件。

3.5BookSingleView中只implements View.onClickListener这个接口,实现了onClick()函数
3.6其他没有了。把这些全都去掉,发现还是不好使
3.7疯了,试试debug模式,把断点打在FlipViewController中的cards.handlerEvent()中,断点既走if()又走else(),已吐晕在厕所。
3.8把断点打在自定义view的onTouchEvent()中,发现编译器走了onTouchEvent方法,但不走打印log方法,卧槽?
3.9上网查了查,以上2点原因可能是因为编译器把断点都打在内存上,点击图片时,多次执行onTouchEvent方法造成内存紊乱,编译器紊乱,只能打印log查看,但是log()方法还不走,卧槽?卧槽?卧槽?
3.10难道是我自定义view不对么,新建个空android项目,把自定义ImageView拉进去,发现onTouchEvent()中的log还是不打印。
3.11整个步骤3已花费1天时间,最后只能怀疑编译器不好使了,用回eclipse,新建空Android项目,重写onTouchEvent()方法,发现全都正常打印,我tm被Androidstudio坑了一下午!@#¥%……&*()
3.12要不是因为65536的错误,早都抛弃androidstudio了,当时谁和我说Androidstudio用时间长了不会想念eclipse的,我干死他。
3.13没办法,正常日志不打印,能不能有别的地方能看打印日志,搜了搜,打开tools->android->android device monitor,在ddms中查看底部的logcat日志,这回能看到了。wtf!!!!
4、自定义view中重写ontouchEvent()之后发现只响应ActionDown方法,不响应ActionUp和ActionCancel方法,晕。
4.1搜了一下,是因为ontouchEvent()响应ActionDown之后,返回的是false,导致接下来的UP和Cancel事件无法被响应,所以改成这样
 
 
@Override
public boolean onTouchEvent(MotionEvent event) {
    
	Log.i("","ImageViewFlipInside onTouchEvent: " +event.getAction());
    switch(event.getAction){
		case MotionEvent.ActionDown:
			Log.i(“”,”onTouchEvent ActionDown”);
		return true;
		case MotionEvent.ActionUp:
			Log.i(“”,”onTouchEvent ActionUp”);
		break;	
		case MotionEvent.ActionCancel:
			Log.i(“”,”onTouchEvent ActionCancel”);
		break;	
	}
    return super.onTouchEvent(event);
}
4.2这回up和cancel事件都能响应到了,但是滑动事件又被拦截了,WTF!
4.3所以就不能靠响应UP和Cancel事件来判断图片被点击。
4.4所以改成双击图片放大,放大代码为:
 
 
long exitTime = 0;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("","ImageViewFlipInside onTouchEvent: " +event.getAction());
        if (event.getAction() == MotionEvent.ACTION_DOWN) {

            //点击了子控件标识
            common.isChildViewClicked = true;

            if ((System.currentTimeMillis() - exitTime) > 200) {
                exitTime = System.currentTimeMillis();
            } else {
                Intent intent = new Intent(context, ShowMatrixImageActivity.class);
                intent.putExtra("imgurl", (String)getTag());
                context.startActivity(intent);
            }
        }
        return super.onTouchEvent(event);
    }
5.0问题解决
PS:我想念eclipse
PPS:Androidstudio太烂了,各种设置都设置过了build还是那么慢,心情好2分钟,心情不好10分钟
PPPS:引入库的时候,jcenter有的可以直接compile,jcenter没有的只能down下来修改build.settings和wrapper下的properties使其和Android的gradler版本保持一致,要不然还得上网下,慢死。而且就算能compile,如果别人的库或者sdk或者supportv4或者其他神马的和自己的版本有冲突,就会出现莫名其妙的错误,太tm恶心了,桑心
































猜你喜欢

转载自blog.csdn.net/jbb0403/article/details/54094016