17

I am looking for a way for when a user long touches a mapview (lets say for 1000ms) that i can some how do a certain action.

How would i go about judging how long a user long touches a mapsview(or any view).

It would be similar to android google maps app, when you long touch, it brings up a balloon overlay item.

Edit added

mapView.setOnLongClickListener(new View.OnLongClickListener() {

        public boolean onLongClick(View v) {

            Toast.makeText(mapView.getContext(), "Hello 123", 2000);
            return false;
        }
    });

the above does not work... any ideas why?

Edit added

This is what i am trying at the moment, but it does not seem to work, even if i only press on the phone, it says the event is an action_move,

i am using an inner class in my MapActivity

    private long startTime=0;
private long endTime=0;

class MapOverlay extends Overlay {



    @Override
    public boolean onTouchEvent(MotionEvent ev, MapView mapView) {

        if(ev.getAction() == MotionEvent.ACTION_DOWN){
             //record the start time
             startTime = ev.getEventTime();

             Log.d("LC", "IN DOWN");
          }else if(ev.getAction() == MotionEvent.ACTION_UP){
             //record the end time
             endTime = ev.getEventTime();
             Log.d("LC", "IN UP");
          }else if(ev.getAction() == MotionEvent.ACTION_MOVE){
              Log.d("LC", "IN move");
              endTime=0;
          }

          //verify
          if(endTime - startTime > 1000){
             //we have a 1000ms duration touch
             //propagate your own event
              Log.d("LC", "time touched greater than 1000ms");
              Toast.makeText(getBaseContext(), "Hello 123", Toast.LENGTH_SHORT).show();
              startTime=0; 
              endTime=0;
             return true; //notify that you handled this event (do not propagate)
          }

        return false;//propogate to enable drag

    }

}

and here is my error log that does not make any sense to me

06-29 14:29:55.509: DEBUG/LC(7693): IN move
06-29 14:29:56.149: DEBUG/LC(7693): IN UP
06-29 14:29:56.149: DEBUG/LC(7693): 6346707 6349261
06-29 14:29:56.149: DEBUG/LC(7693): time touched greater than 1000ms

the end time should be set to zero...but it is not...any idea why?

molleman
  • 2,934
  • 16
  • 61
  • 92
  • This worked perfectly! Here's C#/Xamarin version is someone needs: `protected long _touchStartTime; public override bool OnTouchEvent(MotionEvent e){if (e.Action == MotionEventActions.Down) _touchStartTime = e.EventTime; if (e.Action == MotionEventActions.Up && e.EventTime - _touchStartTime > 1000) DoSomethingFun(); return base.OnTouchEvent(e);}` – BayssMekanique Jul 21 '14 at 15:41
  • Hello, did you figure out how to do the action if user pressed the button for certain time (lets say 1000ms) ? – Syed Rafay Mar 25 '18 at 13:56
  • [Here](https://stackoverflow.com/questions/10946751/ontouch-onlongclick-together-in-android) some useful answers. Even in the end ;) – dvn Jul 21 '20 at 04:31

6 Answers6

8

This is how do you normally create an onLongClickListener. Try this:

mapView.setOnLongClickListener(new OnLongClickListener() {

        @Override
        public boolean onLongClick(View arg0) {

            Toast.makeText(mapView.getContext(), "Hello 123", 2000);

            return false;

        }
    });

Reference to your edit:

This might be the way to get what you want.

private final Handler handler = new Handler();
private final Runnable runnable = new Runnable() {
public void run() {
     checkGlobalVariable();
}
};

// Other init stuff etc...

@Override
public void onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
    // Execute your Runnable after 1000 milliseconds = 1 second.
    handler.postDelayed(runnable, 1000);
    mBooleanIsPressed = true;
}

if(event.getAction() == MotionEvent.ACTION_UP) {
    if(mBooleanIsPressed) {
        mBooleanIsPressed = false;
        handler.removeCallbacks(runnable);
    }
}
}

And now you can check with checkGlobalVariable function:

if(mBooleanIsPressed == true)

This is how you can handle this case. Good luck.

Umit Kaya
  • 5,771
  • 3
  • 38
  • 52
  • 1
    @molleman I guess **Umitk** give you right way for realising long click. His code it's exactly how longClock works in original Android views. – Igor Tyulkanov Jun 05 '14 at 02:53
4

Your are probably looking for a normal long click? You will have to set your view to be long clickable by adding android:longClickable to your views xml, or by calling setLongClickable(true). Then you can add an OnLongClickListener to the view. I dont know of a way to determine exactly how long the long click is. But the default long click is the same as the google maps long click that you mentioned.

OnLongClickListener

snowstreams
  • 575
  • 2
  • 13
  • 23
3

You can set up a longClickListener and a touchListener. Add a boolean class data member variable longClicked and set it to false initially. This is how you can set the longClickListener.

    view.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            longClicked = true;
            return false;
        }
    });

For touchListener

    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(longClicked){
                //Do whatever you want here!!
                longClicked = false;
            }
            return false;
        }
    });

It will give you the same effect as google maps long click. Hope it helps.

Jeetendra Gan
  • 165
  • 13
  • It works, just need to do one correction here, you should enable **setOnTouchListener** from **onLongClickListener**, so that it will enable touch listener. Just like that v.setOnTouchListener(this) – Ritesh Adulkar May 20 '19 at 05:44
1

use System.currentTimeMillis() instead of ev.getEventTime();

meh
  • 22,090
  • 8
  • 48
  • 58
0

When MotionEvent.ACTION_UP, endTime will be set to ev.getEventTime(), this make setting endTime to zero when MotionEvent.ACTION_MOVE be not affect. Instead of setting endTime to zero, you should set startTime to ev.getEventTime()

eleven
  • 41
  • 1
  • 8
0

This is how I use long and short touches

View.setOnTouchListener(new View.OnTouchListener() {
        double firsttouch=0;
        boolean isup=false;
        int millistotouch=1000;
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

            if (motionEvent.getAction()==MotionEvent.ACTION_DOWN) {
                firsttouch = (double) System.currentTimeMillis();
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (!isup) {
                             //
                             // Do your long click work
                             //
                            }
                            else
                            {
                                firsttouch=0;
                                isup=false;
                            }
                        }
                    }
                }, millistotouch);
                return true;
            }
            if (motionEvent.getAction()==MotionEvent.ACTION_UP) {
                if (((double) System.currentTimeMillis()-firsttouch)<millistotouch)
                {
                    isup=true;
                    //
                    // Do your short click work
                    //
                }

            }
            return false;
        }
    });
ProY
  • 59
  • 1
  • 5
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 27 '21 at 07:57