3

I want two separate event for long click Down and Long click up. How can I do this in Android?

What I have tried is as follows

public class FfwRewButton extends ImageButton {

    public interface ButtonListener {

        void OnLongClickDown(View v);

        void OnLongClickUp(View v);
    }

    private ButtonListener mListener;

    private boolean mLongClicked = false;

    public FfwRewButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setFocusable(true);
        setLongClickable(true);
    }

    public FfwRewButton(Context context) {
        this(context, null);
    }

    public FfwRewButton(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.imageButtonStyle);
    }

    @Override
    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
        Log.d("my listener", "long press");
        mLongClicked = true;
        mListener.OnLongClickDown(this);
        return super.onKeyLongPress(keyCode, event);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d("my listener", "key down");
        mLongClicked = false;
        if (true) {
            super.onKeyDown(keyCode, event);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        Log.d("my listener", "key up");
        if (mLongClicked)
            mListener.OnLongClickUp(this);
        return super.onKeyUp(keyCode, event);
    }

    public void setFfwRewButtonListener(ButtonListener listener) {
        mListener = listener;
    }
}

and in an activity I called it like this

private FfwRewButton.ButtonListener mListener = new FfwRewButton.ButtonListener() {

        @Override
        public void OnLongClickUp(View v) {
            Log.d(TAG, "longClickup");
        }

        @Override
        public void OnLongClickDown(View v) {
            Log.d(TAG, "longClickdown");
        }
    };

But still am not getting any of the Log messages in logcat Can anyone help me; where I am wrong ?

Androider
  • 2,884
  • 5
  • 28
  • 47
Charan Pai
  • 2,288
  • 5
  • 32
  • 44

4 Answers4

7

onKeyXXX() methods are for Key Events from keyboard or hard keys such as menu key, search key, and so on.

If you want to detect touch events, which is called MotionEvent in Android, you have to override onTouchEvent(MotionEvent e) method and use GestureDetector class for identifying long press.

private GestureDetector mGestureDetector;

public FfwRewButton(...) {
    //....
    mGestureDetector = new GestureDetector(context, 
        new GestureDetector.SimpleOnGestureListener() {
            public boolean onDown(MotionEvent e) {
                mLongClicked = false;
                return true;
            }
            public void onLongPress(MotionEvent e) {
                mLongClicked = true;
                // long press down detected
            }
        });
    }

    public boolean onTouchEvent(MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
        if (mLongClicked && e.getAction() == ACTION_UP) {
           // long press up detected
        }
    }
}
fawaad
  • 341
  • 6
  • 12
Jiyong Park
  • 664
  • 3
  • 6
  • something like this is probably better than what I proposed since it uses a real listener to pick up the normal long click instead of relying on manually tracking the time like mine did. – FoamyGuy Feb 14 '13 at 14:47
  • how to connect my button to this gesturedetector ? – Charan Pai Feb 14 '13 at 15:21
  • It is already connected. If you look at the onTouchEvent() method in your FfwRewButton class, it calls onTouchEvent() method of the GestureDetector object. – Jiyong Park Feb 14 '13 at 15:31
3

Something like this will get you on the right path,

I didn't compile so you may have to correct a few syntax things but your goal can be achieved with this concept

OnTouchListener mTouchListener = new OnTouchListener(){
  private totalTimeDown = -1;
  private downTime = -1;
  public boolean onTouch(View v, MotionEvent me){
    if(me.getAction() == MotionEvent.ACTION_DOWN){
        downTime = System.getCurrentTimeInMillis();
        return true;
    }

    if(me.getAction() == MotionEvent.ACTION_UP){
        totalTimeDown = System.getCurrentTimeInMillis() - downTime;
        if(totalTimeDown > 500){
            //Finger was down long enough for "longClick"
            return true;
        }
    }
    return false;
  }
});
FoamyGuy
  • 46,603
  • 18
  • 125
  • 156
0
holder.layout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch(event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                holder.layoutItem.setVisibility(View.GONE);
                                holder.layoutDelete.setVisibility(View.VISIBLE);
                            }
                        }, 1000);
                        // PRESSED
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        holder.layoutItem.setVisibility(View.VISIBLE);
                        holder.layoutDelete.setVisibility(View.GONE);
                        // RELEASED
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });
Mustofa Kamal
  • 616
  • 7
  • 13
0

You can use this solution to detect the Gesture

val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
            override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
                // Perform single click
                return true
            }

            override fun onLongPress(e: MotionEvent) {
                // Perform your action on long press
                super.onLongPress(e)
            }
        })

Now, set your gesture to touch the listener of the view

holder.itemView.setOnTouchListener(View.OnTouchListener { view, e ->
            gestureDetector.onTouchEvent(e)
            if (e.getAction() == MotionEvent.ACTION_UP) {
             //Perform your action when the user takes their finger off
            }
            return@OnTouchListener true
        })
rNkL
  • 376
  • 3
  • 11