Search code examples
androidheaderscrollviewfooter

Need a Header, Footer, and ScrollView in between. Current code not working


I have been searching through here, and other websites for the last hour trying to figure out what I'm doing wrong. As the title indicates, I need a header w/ buttons, a scrollview, and then a footer with buttons. I want both the header and footer to always be visible. Everything that find says to make a relativelayout, align it to parent top, create a footer, align it to parent bottom, then create a scrollview set it above the footer, and below the header. For some reason my code just decides to ignore that though.

<RelativeLayout
    android:id="@+id/topBar_id"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:background="@color/colorBackground">

    <Button
        android:id="@+id/charInfoBtn_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="General"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

</RelativeLayout>

<ScrollView
    android:id="@+id/genLayoutScroll_id"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@id/bottomBar_id"
    android:layout_below="@id/topBar_id>

    <LinearLayout
      //bunch of junk that users scroll through
    </LinearLayout>

</ScrollView>

<RelativeLayout
    android:id="@+id/bottomBar_id"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    android:background="@color/colorBackground">

    <Button
        android:id="@+id/genApplyBtn_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Apply"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</RelativeLayout>

Using this as my current code, the scrollview sits on top of both the top bar and the bottom bar.

If I remove the layout_above and layout_below lines, and replace it with app:layout_constraintBottom_toTopOf="@id/bottomBar_id" then the scrollview no longer goes over my bottom bar, but now the top bar, and the top of the scrollview is missing.

Then I add app:layout_constraintTop_toBottomOf="@id/topBar_id" to the scrollview, and it goes back to the same as having layout_below and layout_above.

I'm sure I'm missing something here, I just can't figure out what it is that I'm missing. Hoping somebody can point out the dumb mistake I'm making.

P.S. I know some of my code is kind of sloppy right now, mostly due to the fact of trying to figure out this issue.


Solution

  • The simplest way to do this, by far, will be to use a vertical LinearLayout as the root of your view, and use the concept of "layout weight" to make the middle element (the ScrollView) fill the screen.

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/charInfoBtn_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="General"/>
    
        <ScrollView
            android:id="@+id/genLayoutScroll_id"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">
    
            <!-- your contents here -->
    
        </ScrollView>
    
        <Button
            android:id="@+id/genApplyBtn_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Apply"/>
    
    </LinearLayout>
    

    If you need multiple buttons in each bar, you can wrap them in a horizontal LinearLayout.

    The reason this works is the android:layout_weight="1" attribute on the <ScrollView> tag. Assigning weight to a single view will make it take up all remaining space, after the other views take what they need. So your buttons get as much space as they want, and the scroll view gets the rest. Since it's in the middle, this necessarily pushes the bottom button down to the end of the screen.