How to combine OnClickListener and OnTouchListener for an ImageButton

后端 未结 5 426
一整个雨季
一整个雨季 2020-12-10 01:12

I need to do something when the user clicks the ImageButton I\'ve tried to create a static class that implements both OnClickListener

相关标签:
5条回答
  • 2020-12-10 01:31

    There are many solutions for this problem, the best one for me is to eliminate totally the setOnClickListener and inside the onTouchListener do check if the action is ACTION_UP and then inside that check if the last before that is ACTION_DOWN:

    case MotionEvent.ACTION_UP:
        if (lastAction == MotionEvent.ACTION_DOWN) {
            //code for click   
            .
            .
            lastAction = event.getAction();
        }
    

    lastAction is int and I update it at the end of each ACTION

    0 讨论(0)
  • 2020-12-10 01:32

    Use return false instead of return true

    0 讨论(0)
  • 2020-12-10 01:45

    The onTouchListener is able to handle both movements.

    Switch between event.action() values to obtain MotionEvent.

    case MotionEvent.ACTION_DOWN: is the first finger impact.
    case MotionEvent.ACTION_UP: is when the finger goes away.

    You'll have to set the impact point on ACTION_DOWN.

    TheImpactPoint=event.getX();

    And then obtain the distance with ACTION_UP

    float distance =TheImpactPoint-event.getX();

    If distance = 0 then there is a click, otherwise it would be more or less than zero depending on gesture.

    So this is the way to use the click event without a real click event and using only the onTouchListener.

    Hope will be useful.

    0 讨论(0)
  • 2020-12-10 01:53

    Since both actions consist of the gestures "put finger on screen - lift finger from screen" you can't determine if it was touch action or a click action. So if you implement both listeners on this image button, a touch/click will change the picture AND press the button. Not sure if there is a determined order of these events...

    However, if you want to separate these events, you will either need to define to a different gesture to one of the actions (like wiping to change picture), or create different areas who handle the events, for example the image doesn't fit the whole button and the free area serves as button click area.

    HTH

    Update:

    I figured out, that a TouchEvent is more general than a ClickEvent thus it is called first.

    public abstract boolean onTouch (View v, MotionEvent event)
    

    This returns true, if the listener has consumed the event, false otherwise. So you can decide in your implementation if the Event should also be handled by OnClickListener, then just return false.

    0 讨论(0)
  • 2020-12-10 01:54

    Use this code:

    public class GestureHelper implements OnTouchListener {
    
    private final GestureDetector mGestureDetector;
    
    public GestureHelper(Context context) {
        mGestureDetector = new GestureDetector(context, new GestureListener(this));
    }
    
    public void onSwipeRight() {
    };
    
    public void onSwipeLeft() {
    };
    
    public void onSwipeTop() {
    };
    
    public void onSwipeBottom() {
    };
    
    public void onDoubleTap() {
    };
    
    public void onClick() {
    };
    
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }
    
    private static final class GestureListener extends SimpleOnGestureListener {
    
        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;
        private GestureHelper mHelper;
    
        public GestureListener(GestureHelper helper) {
            mHelper = helper;
        }
    
        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            mHelper.onClick();
            return true;
        }
    
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            mHelper.onDoubleTap();
            return true;
        }
    
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            mHelper.onSwipeRight();
                        } else {
                            mHelper.onSwipeLeft();
                        }
                    }
                } else {
                    if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            mHelper.onSwipeBottom();
                        } else {
                            mHelper.onSwipeTop();
                        }
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return result;
        }
    }
    
    }
    

    Extend this class and use like this...

    view.setOnTouchListener(new SomeYourGestureHelper(context, someParameters));
    
    0 讨论(0)
提交回复
热议问题