Android - show/hide fragment leaves an empty area

Bostone picture Bostone · May 21, 2012 · Viewed 11.7k times · Source

Given:

  1. Two vertically placed elements on the screen (ViewPager and Fragment)
  2. Action in the first currently selected fragment (ViewFlipper) toggles between text-based and WebView-based view in the top fragment and hides/shows bottom fragment.

Observed:

  1. Hiding the bottom fragment leaves an empty space where the bottom fragment is located.

I tried both Relative and LinearLayout (with top fragment set to weight=1) but both have no effect after bottom fragment is removed I still have empty space on the bottom

Here's top level layout file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="fill_parent"
    android:layout_height="0dip" android:layout_weight="1"/>

<!-- This gets replaced with appropriate fragment at run time -->
<LinearLayout
    android:id="@+id/scrollFragmentPlaceholder"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="110dip" />
</LinearLayout>

Here's code that toggles the fragment

    Fragment scroll = getSupportFragmentManager().findFragmentById(R.id.scrollFragment);
    if (scroll.isHidden() == isWebView)
        return; // already handled, do nothing
    FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
    if (scroll != null && scroll.isAdded()) {
        if (isWebView) {
            tr.hide(scroll);
        } else
            tr.show(scroll);
    }
    tr.commit();

And here's how it looks: Bottom fragment is hidden

Answer

Bostone picture Bostone · Jun 13, 2012

A month later I figured out how to do it. Turns out that simply hiding the fragment is not enough, basically I need to hide/show the shell containing the fragment. It is still the LinearLayout that was originally defined in XML. In fact, it's sufficient to set visibility on that original layout to show/hide the fragment. So the code from the question now looks like this:

public void onJobViewToggled(final boolean isWebView) {
    if (isFinishing())
        return;
    final Fragment scroll = getSupportFragmentManager().findFragmentById(R.id.scrollFragment);
    if (scroll.isHidden() == isWebView)
        return; // already handled, do nothing
    final FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
    if (scroll != null && scroll.isAdded()) {
        if (isWebView) {
            tr.hide(scroll);
            // shell is the original placeholder
            shell.setVisibility(View.GONE);
        } else {
            tr.show(scroll);
            shell.setVisibility(View.VISIBLE);
        }
    }
    tr.commit();
}

Note that you still want to show/hide the fragment for this to work