Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make a FrameLayout fill the height of its parent so the whole page scrolls together?

Tags:

android

I have a FrameLayout that loads Fragments by tapping on tabs in a TabWidget. I can't figure out how to make the height of the FrameLayout as tall as its content, so that the whole containing ScrollView will scroll together as one instead of a separate scrolling view.

Here's a visual example of this Fragment's structure:

enter image description here

As you can see, the Frame Layout Visible Height only reveals one row of the Fragment, when in fact, there are a few. I can scroll within the FrameLayout to see the other rows as it is now, but that's not what I'm going for. The FrameLayout is made up of a LinearLayout containing a GridView with their layout_heights set to wrap_content.

I tried hardcoding the height of the FrameLayout to something like 500dp and it works great except for the fact that it's no longer dynamically sized. Would I need to resize the FrameLayout programmatically each time a new image is loaded into the inner content? Is there a layout attribute I can set so it'll stretch its height to match its inner content?

Here's my layout xml file:

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

    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="200dp">
        <!-- CONTAINS USER INFO AND STATS -->
    </RelativeLayout>
    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="#ffffff">
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="60dp"
                android:weightSum="2">
            </TabWidget>
            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                >
            </FrameLayout>
        </LinearLayout>
    </android.support.v4.app.FragmentTabHost>
</LinearLayout>
</ScrollView>

Thank you!


Since I'm going to set a bounty on this, I thought I'd share what I've figured out so far.

In the thumbnails, onSuccess when each image is loaded, I'm calling a function in the GridLayout that holds the images that counts the images and sets the height of the GridLayout. This works fine, although it seems like it'd be a bit inefficient.

What I'm doing is setting the GridLayout height and then calling requestLayout and invalidate on it and it's parent(s). This works, but not as the images loading. It'll work if I go to a different tab and return to the thumbnails, oddly enough. Which makes me think I'm not updating at the right time or on the right object.

Anyway, that said. Does anyone know how to make the height of a GridLayout expand to hold its contents (instead of scrolling) so I can scroll the entire page (including the top section)?


I should also add the GridView layout:

<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/grid"
android:stretchMode="columnWidth"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
android:fastScrollAlwaysVisible="false"
android:fastScrollEnabled="false"
android:numColumns="3"
android:choiceMode="none">
</GridView>
like image 700
Keith Avatar asked Oct 24 '14 08:10

Keith


People also ask

Why does FrameLayout hold one view?

Frame Layout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other.

How many Childs FrameLayout can have?

What is the maximum number of Children Views inside a FrameLayout in Android? There's no limit indicated on how many children that a ViewGroup can have on the docs.

What's a FrameLayout When should you use FrameLayout instead of RelativeLayout?

A common rule of thumb when choosing layouts is to select the combination that results in the smallest number of nested layout views. Specific to your question, RelativeLayout is larger and more capable than the much simpler FrameLayout. So for simple layouts, the latter is probably more efficient.

What is the use of frame Layout?

Android Framelayout is a ViewGroup subclass that is used to specify the position of multiple views placed on top of each other to represent a single view screen. Generally, we can say FrameLayout simply blocks a particular area on the screen to display a single view.


1 Answers

I was in a similar situation but I had a ListView instead of a GridView. You are right in the part when you have to set the height dynamically each time you add an item or if you call notifyDataSetChanged().

THIS CODE IS FOR LISTVIEW WITH DIFFERENT HEIGHT FOR EACH ROW

private void setListViewHeightBasedOnChildren(MyQueueAdapter listAdapter) {

    int desiredWidth = MeasureSpec.makeMeasureSpec(
            mListView.getWidth(), MeasureSpec.AT_MOST);
    int totalHeight = 0;

    View view = null;
    int i;
    for (i = 0; i < listAdapter.getCount(); i++) {
        view = listAdapter.getView(i, view, mListView);

        view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);

        totalHeight += view.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = mListView.getLayoutParams();
    params.height = heightList
            + (mListView.getDividerHeight() * (listAdapter
                    .getCount() + 3));

    heightListComplete = params.height;
    mListView.setLayoutParams(params);

}

You need to modify this code according to your needs, you don't need the loop as the height of each row is static in your case. If you need more help let me know.

ALTERNATIVE

If you know the height of the view in dp you can easily convert the dp in px and set the height of your gridview according to number of rows.

like image 135
Naveen Avatar answered Sep 30 '22 00:09

Naveen