8

I'm currently starting to develop Android applications and I've been following up a this tutorial on how to use and improve the Google maps application.

I've managed to show up on screen the map, on touch I get the address of a location (via Reverse Geocoding) with the showing of a Toast. But here is my problem - when you click a number of consecutive times over the map you will get all the toasts one after other and each of them will take his time (in my case - Toast.LENGTH_LONG) to disappear. I want to make the application automatically close the older toast and show a new toast with the new address clicked.

In other resources I found I should use the toast.cancel() method for this purpose, but I experience trouble using it - I have already overrided the onTouchEvent - how can I detect there is a new touch over the map while the toast is showing? Or maybe you would suggest me a better way of hiding the already open toast?

I've tried to make my Toast address a global one, but it wasn't working also.

Here is my code for the application:

@Override
public boolean onTouchEvent(MotionEvent event, MapView mapView) {   
    //---when user lifts his finger---
    if (event.getAction() == 1) {                
        GeoPoint p2 = mapView.getProjection().fromPixels((int) event.getX(), (int) event.getY());
        Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
        try {
            List<Address> addresses = geoCoder.getFromLocation(p2.getLatitudeE6() / 1E6,
                    p2.getLongitudeE6() / 1E6, 1);
            String add = " ";
            if (addresses.size() > 0) 
                for (int i=0; i<addresses.get(0).getMaxAddressLineIndex();i++)
                    add += addresses.get(0).getAddressLine(i) + "\n";
            Toast address;
            address = Toast.makeText(getBaseContext(), add, Toast.LENGTH_LONG);
            address.show();                     
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
    return false;
}
Kara
  • 6,115
  • 16
  • 50
  • 57
Stefan Doychev
  • 711
  • 3
  • 12
  • 30
  • How is toast.cancel() not working? Is it being called? – James Lim Jul 19 '11 at 08:22
  • Also, I would recommend using `ACTION_UP == event.getAction()` instead of `event.getAction() == 1`. It is just good style. – James Lim Jul 19 '11 at 08:26
  • possible duplicate of [How to cancel Toast created in a different method on android?](http://stackoverflow.com/questions/5503682/how-to-cancel-toast-created-in-a-different-method-on-android) – Wroclai Jul 19 '11 at 09:34
  • Thanks, @Pompe de velo - this is what I was searching for! Tack – Stefan Doychev Jul 19 '11 at 10:04

2 Answers2

22

You don't show where you have Toast address as a global, but you are creating a new, local Toast object each time you click with:

Toast address;
address = Toast.makeText(getBaseContext(), add, Toast.LENGTH_LONG);
address.show();

Which will override the global object you are creating. I'd recommend having address as a private static object in your class to ensure that address will always be the same object no matter how many times you click so that you are always cancelling the Toast that you last showed (since there is only ever one), and remove the local declaration:

private static Toast address;

...

if (address != null)
    address.cancel();

address = Toast.makeText(getBaseContext(), add, Toast.LENGTH_LONG);
address.show();
RivieraKid
  • 5,923
  • 4
  • 38
  • 47
  • I've moved the `private static Toast address;` declaration as a global one. If now I use the address.cancel() method it will just cancel my toast and nothing will show - how to call the cancelling of a toast only when there is a new touch on the screen? – Stefan Doychev Jul 19 '11 at 08:44
  • Just call `address.cancel()` in your onTouchEvent before you show the new toast - this will cancel an existing toast if there is one (either showing or waiting to be shown) I've updated my suggestion to include this. – RivieraKid Jul 19 '11 at 09:28
  • I tried with the `address = Toast.makeText(getBaseContext(),add, Toast.LENGTH_LONG); address.cancel(); address.show();` but I get the same result - the toast changes only after it's lifetime ends. – Stefan Doychev Jul 19 '11 at 09:53
  • 4
    I found the answer here - http://stackoverflow.com/questions/5503682/how-to-cancel-toast-created-in-a-different-method-on-android `private Toast mToastText; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Create the object once. mToastText = Toast.makeText(this, "", Toast.LENGTH_SHORT); } private void displayText(final String message) { mToastText.cancel(); mToastText.setText(message); mToastText.show(); }` Maybe this was your original idea - thanks! – Stefan Doychev Jul 19 '11 at 10:06
  • Your first attempt was cancelling the pending toast before you displayed it, the second one you found is exactly the kind of thing I was going for - glad you solved your problem. – RivieraKid Jul 19 '11 at 10:43
  • Does not work! Use http://stackoverflow.com/questions/5503682/how-to-cancel-toast-created-in-a-different-method-on-android – ʞᴉɯ Sep 12 '13 at 15:16
1

You need to get instance when create Toast by call make().After that before you show new toast, you should cancel old Toast.GoodLuck!

duonghv
  • 346
  • 2
  • 4
  • Is the `Toast.makeText` working the same way as `make()` ? Here I have a question - on the beginning of my OnTouchEvent method I can have a check for an already open toast - if there is an open one - cancel it and procede forward with the opening of a new one. But is there a build-in method for check for the existance of an open toast? – Stefan Doychev Jul 19 '11 at 08:48
  • RivieraKid mention the solution which is same with my way. – duonghv Jul 20 '11 at 02:54
  • I didn't got yours previously, now I know how it's done I quite undestand it - thanks. – Stefan Doychev Jul 20 '11 at 09:42