moagrius / TileView

TileView is a subclass of android.view.ViewGroup that asynchronously displays, pans and zooms tile-based images. Plugins are available for features like markers, hotspots, and path drawing.
MIT License
1.46k stars 337 forks source link

Disable user interaction on demand #465

Closed tkrz closed 6 years ago

tkrz commented 6 years ago

Hi, i have to disable user interaction in some scenarios, so that user cannot modify position, where TileView has stopped, or click anywhere on TileView. I've seen that some do it by modifying onTouchEvent to return false. Is there a better way to do something like that?

ameron32 commented 6 years ago

All I can offer you is another way to do that. Perhaps less code or more consistent results than "onTouchEvent return false".

If you create an empty view and tileView.addView(view) this will put it above all other views and first in line for touch events. Add a View.OnTouchListener to this empty view to handle these touch events. Return true if you want to take the event(s) and prevent other views beneath it to ever receive it. Return false to pass the events through, as if the view wasn't even there.

    View view = new View(context);
    // make sure it captures the entire surface of the TileView. 
    // we don't let any touch events go around us.
    LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
    view.setLayoutParams(lp);

    view.setOnTouchListener(new View.OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
                // return true to disable interaction on all views beneath this view
                // return false to allow all interactions normally
                return false;
          }
    };
    tileView.addView(view); // above all other views in the TileView

If you put this view on top of everything, you can prevent all interactions (with return true). If you put the view underneath some views and above others, you can selectively restrict the lower views but allow the upper views.

Options:

    // return true allows touch for markers and callouts, while blocking ZoomPan events
    tileView.addView(view, 3); 

    // return true allows touch for callouts, while blocking markers and ZoomPan events
    tileView.addView(view, 4); 

    // return true blocks touch for markers, callouts, and ZoomPan events
    tileView.addView(view); 

Think of it as a glass case in a museum. You can see the artifact, but when you try to touch it, you get stopped at the glass (return true).

Now, you can build your own logic to return true or false where you need to allow and restrict touch interactions. Just remember: don't put your controls below your empty view or you won't be able to interact with them either.

Hope this helps! I'm sure there are other solutions, too. I look forward to hearing them.

tkrz commented 6 years ago

Geez, i didn't thought about this... Well, it seems that this is quickest and most simple solution.