Android fixed Header and Footer with scrollable content layout example
Introduction
Application user-interfaces that require a fixed header and footer are easy to implement in the Android development ecosystem. One may also need the content to be scrollable in case it does not fit between the header and footer boundaries.
In this tutorial we will implement an Android fixed header and footer activity which content will be scrollable. Finally we will make this layout a template so it can be defined in a single location and reused across multiple activities.
You may also find interesting to read the following tutorial where we show how to implement a simple header and footer Android activity layout: Android Header and Footer layout example.
Used software:
- Android SDK 21.0.0
The Activity Layout
We will start by defining an Android activity with fixed header and footer and also scrollable content:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- Header aligned to top --> <RelativeLayout android:id="@+id/header" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:background="#AFA7EF" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="Header" android:textColor="#000000" android:textSize="20sp" /> </RelativeLayout> <!-- Footer aligned to bottom --> <RelativeLayout android:id="@+id/footer" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#6AED83" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="Footer" android:textColor="#000000" android:textSize="20sp" /> </RelativeLayout> <!-- Scrollable Content below header and above footer --> <ScrollView android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@id/footer" android:layout_below="@id/header" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 1" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 2" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 3" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 4" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 5" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 6" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 7" android:textColor="#FFFFFF" android:textSize="20sp" /> </LinearLayout> </ScrollView> </RelativeLayout>
Basically we defined a main RelativeLayout serving as the activity container. Then we defined the header aligned to the top of the main container and the footer aligned to the bottom of the main container. The content is finally wrapped inside a ScrollView so it becomes scrollable in case its height exceeds the boundaries determined by the header and the footer.
When we launch our activity the following user interface will be generated:
We may scroll down in order to see the remaining content:
Making it a reusable template
Now let's create a template so we may define the layout in a single place and reuse it across multiple activities:
First we extract the common sections of the original layout and create a new layout in a separate file. We called it headerfooter_activity.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- Header aligned to top --> <RelativeLayout android:id="@+id/header" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:background="#AFA7EF" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="Header" android:textColor="#000000" android:textSize="20sp" /> </RelativeLayout> <!-- Footer aligned to bottom --> <RelativeLayout android:id="@+id/footer" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#6AED83" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="Footer" android:textColor="#000000" android:textSize="20sp" /> </RelativeLayout> <!-- Scrollable Content below header and above footer --> <ScrollView android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@id/footer" android:layout_below="@id/header" > <!-- Content will go here --> </ScrollView> </RelativeLayout>
Note that the ScrollView is now empty and ready to hold any content we need.
Now we define our previous sample TextView's activity content as content.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 1" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 2" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 3" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 4" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 5" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 6" android:textColor="#FFFFFF" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:layout_marginTop="25dp" android:text="Content 7" android:textColor="#FFFFFF" android:textSize="20sp" /> </LinearLayout>
Finally we instruct the activity to load the template and set the content as our sample content:
package pt.webprods.android.file.manager.pro.views.v2; import pt.webprods.android.file.manager.pro.R; import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.widget.ScrollView; public class HeaderFooterActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // Set main layout as the template setContentView(R.layout.headerfooter_activity); // Inflate the content into the container ScrollView container = (ScrollView) findViewById(R.id.container); getLayoutInflater().inflate(R.layout.content, container); } }
Now you may replace the sample TextView's content with any content you need and reuse the headerfooter_activity template in multiple activities.
A step further into modularization
We may take a step further into modularization by externalizing the header and footer into separate files. You may find more info about externalizing the header and footer in the following article: Android Header and Footer layout example.