An invisible layout behind the fragment is getting clicked:
Asked Answered
G

5

35

I have created several fragments and I add the first fragment the following way:

mainFragment = (MainFragment) MainFragment.create();
    getSupportFragmentManager().beginTransaction()
    .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right)
    .add(R.id.content, mainFragment, MAIN_FRAGMENT_TAG)
    .commit();

The second fragment is added this way:

     getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right)
    //.hide(mainFragment)
    .add(R.id.content,VenueFragment.create(vid), "Venue Fragment")
    .addToBackStack(null)
    .commit();
    setDrawerIndicatorEnabled(false);

Now as you see the hide method is not applied for this transaction, and the VenueFragment is opened, the problem in this case is that while the VenueFragment opened (and it's a full screen view) pressing on empty section of this fragment invokes calls of the MainFragment clickable views. How can I prevent this?

If I use the hide option then it's not happening but for some reason the animation for removing the MainFragment is going up and that makes a weird experience.

Giddings answered 15/1, 2014 at 15:45 Comment(2)
Set clickable property on the second fragment's view to true. <LinearLayout xmlns:android="schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" />Bobbitt
@faiziii, if you look carefully you will notice that this is exactly what specified in the accepted answer.Giddings
R
46

You need to make the root ViewGroup of VenueFragment clickable so it handles click events and they do not pass down (in the z-order sense) to the other Fragment.

Rondeau answered 15/1, 2014 at 15:46 Comment(6)
you mean in the second Fragment I have added the VenueFragment?Giddings
Ok, but even if this works, it looks like kinda of a work around. Not something Google has intended to be that way or to be handled like this. Is there any other way to handle this problem?Giddings
I do not know. I faced this same problem and that was the only solution I found. There has to be another way.Rondeau
Well now we know why this happens, which actually makes some sense now. And your answer was the easiest one to complete. So thanks.Giddings
well I have to admit my initial thought was "lol, wtf dude" when I saw your solution...but it just WORKS ! Thanks.Mehta
I understand the logic in this and if this is still active, I would like to know what if there are clickable text in the layout(ViewGroup) that was made Clickable, how would we handle that?Furmark
R
22

Set clickable property on the second fragment's view to true.

For Example:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true" />
Reign answered 19/7, 2016 at 5:6 Comment(0)
L
7

Setting an onClickListener on VenueFragment will work, but I'll add a little bit more explanation. Having the main fragment get a touch event is intended behavior to handle the case where your venue fragment is transparent. In that case, it could be reasonable to expect the touch to go through your transparent view to the one underneath. As such, android passes touch events until they can be handled. Setting an onClickListener will handle the event, preventing it from being passed to the next View. If you wanted to be "correct" about preventing clicks on the lower fragment, there are a couple of options:

  1. Remove the onClickListener from the main fragment in OnPause, and set it in OnResume. That way, any time the main fragment is not the active fragment, it cannot be clicked.
  2. Subclass your top level layout in your VenueFragment and override OnTouchEvent to return true. This will essentially do the same thing as setting an onClickListener, but you may find that it makes your intention to block all touch events clearer.
Longford answered 15/1, 2014 at 18:52 Comment(1)
Thanks for the explanation and +1 for that, but to tell you the truth the option I received in the first answer works and it basically does the same as your second option for fixing this. Only without all the mess of inheritance and then using this custom class in the layout.Giddings
S
3

Well the very quick answer is android:clickable="true" in the top of the layout properties in fragment.

But it would be a better practice if you create an activity with a FrameLayout & its id and no other elements in that activity. So whenever you want a fragment to be on the screen, give a call to that activity and use

getSupportFragmentManager().beginTransaction()
    .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right)
    .replace(R.id.frameLayoutId, mainFragment, MAIN_FRAGMENT_TAG)
    .commit();

use replace instead of add so that the frameLayout of the activity is replaced by the fragment's layout as given by the frameLayoutId

Sporogony answered 4/4, 2017 at 12:13 Comment(0)
D
1

I have a better solution, at least that what I think :P.

while fragment transaction, use hide and show method.

Disciplinarian answered 22/5, 2018 at 12:18 Comment(1)
It's not a better solution, because sometimes you want to leave the back fragment (for example: when the top fragment is not a full-screen fragment). in this case, you need to leave both fragments. what would you do then?Giddings

© 2022 - 2024 — McMap. All rights reserved.