Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android make view disappear by clicking outside of it

I have some views that I make visible upon a button press. I want them to disappear if I click outside of those views.

How would this be done on Android?

Also, I realize that the "back button" can also assist Android users with this - I might use that as a secondary way to close the views - but some of the tablets aren't even using a 'physical' back button anymore, it has been very de-emphasized.

like image 487
CQM Avatar asked Jul 13 '11 21:07

CQM


4 Answers

An easy/stupid way:

  • Create a dummy empty view (let's say ImageView with no source), make it fill parent

  • If it is clicked, then do what you want to do.

You need to have the root tag in your XML file to be a RelativeLayout. It will contain two element: your dummy view (set its position to align the Parent Top). The other one is your original view containing the views and the button (this view might be a LinearLayout or whatever you make it. don't forget to set its position to align the Parent Top)

Hope this will help you, Good Luck !

like image 186
iTurki Avatar answered Oct 22 '22 02:10

iTurki


Find the view rectangle, and then detect whether the click event is outside the view.

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Rect viewRect = new Rect();
    mTooltip.getGlobalVisibleRect(viewRect);
    if (!viewRect.contains((int) ev.getRawX(), (int) ev.getRawY())) {
        setVisibility(View.GONE);
    }
    return true;
}

If you want to use the touch event other place, try

return super.dispatchTouchEvent(ev);
like image 43
Kai Wang Avatar answered Oct 22 '22 03:10

Kai Wang


This is an old question but I thought I'd give an answer that isn't based on onTouch events. As was suggested by RedLeader it's also possible to achieve this using focus events. I had a case where I needed to show and hide a bunch of buttons arranged in a custom popup, ie the buttons were all placed in the same ViewGroup. Some things you need to do to make this work:

  1. The view group that you wish to hide needs to have View.setFocusableInTouchMode(true) set. This can also be set in XML using android:focusableintouchmode.

  2. Your view root, i.e. the root of your entire layout, probably some kind of Linear or Relative Layout, also needs to be able to be focusable as per #1 above

  3. When the view group is shown you call View.requestFocus() to give it focus.

  4. Your view group need to either override View.onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) or implement your own OnFocusChangeListener and use View.setOnFocusChangeListener()

  5. When the user taps outside your view focus is transferred to either the view root (since you set it as focusable in #2) or to another view that inherently is focusable (EditText or similar)

  6. When you detect focus loss using one of the methods in #4 you know that focus has be transferred to something outside your view group and you can hide it.

I guess this solution doesn't work in all scenarios, but it worked in my specific case and it sounds as if it could work for the OP as well.

like image 29
britzl Avatar answered Oct 22 '22 03:10

britzl


I've been looking for a way to close my view when touching outside and none of these methods fit my needs really well. I did find a solution and will just post it here in case anyone is interested.

I have a base activity which pretty much all my activities extend. In it I have:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (myViewIsVisible()){
            closeMyView();
        return true;
    }
    return super.dispatchTouchEvent(ev);
}

So if my view is visible it will just close, and if not it will behave like a normal touch event. Not sure if it's the best way to do it, but it seems to work for me.

like image 17
pickle_inspector Avatar answered Oct 22 '22 02:10

pickle_inspector