dinocore1 / DevsmartLib-Android

A Horizontal ListView for Android
http://www.dev-smart.com/archives/34
812 stars 493 forks source link

View flickers when touching button and scrolled #10

Open raghulj opened 12 years ago

raghulj commented 12 years ago

The view is flickered when we hold the button and scroll. When any movement is made by tapping the button the view is flickering. Looks like problem in handling the touch event in the dispatchTouchEvent not sure though.

AEFeinstein commented 12 years ago

I can confirm this bug

vrash commented 12 years ago

Replacing dispatchTouchEvent with @Override public boolean onTouchEvent(MotionEvent event) { boolean handled = mGesture.onTouchEvent(event); return handled; } and

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch( ev.getActionMasked() ){
        case MotionEvent.ACTION_DOWN:
             mInitialX = ev.getX();
             mInitialY = ev.getY();             
             return false;
        case MotionEvent.ACTION_MOVE:
             float deltaX = Math.abs(ev.getX() - mInitialX);
             float deltaY = Math.abs(ev.getY() - mInitialY);
             return ( deltaX > 5 || deltaY > 5 );
        default:
             return super.onInterceptTouchEvent(ev);
    }
}

??

orgmir commented 11 years ago

I can confirm that the previous solution corrects the bug, thanks for that.

httpdispatch commented 11 years ago

@vrash your fix doesn't work properly. It causes big view jumps

kamilzych commented 11 years ago

@httpdispatch well, @vrash fix is almost correct. It's working very good for me after I changed return false; to return true; in case ACTION_DOWN - so:

@Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
    boolean handled = super.dispatchTouchEvent(ev);
    handled |= mGesture.onTouchEvent(ev);
    return handled;
}

@Override
public boolean onInterceptTouchEvent(final MotionEvent ev) {
    switch (ev.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        mInitialX = ev.getX();
        mInitialY = ev.getY();
        //HERE RETURN TRUE INSTEAD OF FALSE
        return true;
    case MotionEvent.ACTION_MOVE:
        final float deltaX = Math.abs(ev.getX() - mInitialX);
        final float deltaY = Math.abs(ev.getY() - mInitialY);
        return deltaX > 5 || deltaY > 5;
    default:
        return super.onInterceptTouchEvent(ev);
    }
}
DollyBansal commented 11 years ago

Thanks @vrash, its solved my problem :)

httpdispatch commented 10 years ago

@kamilzych your approach also has issue. I am testing new one

    float mInitialX;
    float mInitialY;
    boolean mIsMoving;
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // experimental update to avoid view flickers and onclick events fired
        // after move
        boolean handled = mGesture.onTouchEvent(ev);
        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mInitialX = ev.getX();
                mInitialY = ev.getY();
                mIsMoving = false;
                break;
            case MotionEvent.ACTION_MOVE: {
                final float deltaX = Math.abs(ev.getX() - mInitialX);
                final float deltaY = Math.abs(ev.getY() - mInitialY);
                mIsMoving = deltaX > 5 || deltaY > 5;
            }
                break;
        }
        if (!mIsMoving) {
            handled |= super.dispatchTouchEvent(ev);
        }
        return handled;
    }

It also has an issue that child component may not receive ACTION_UP event, but at least view should not flicker and on click works as expected