Android fixed Header and Footer with scrollable content layout example

05 October 2013
By Gonçalo Marques
In this tutorial we will create an Android fixed Header and Footer with scrollable content activity layout.

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:

  1. 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:

Activity layout

<?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:

Actitity with scrolling set to the top
Android activity - scrolling set to the top

We may scroll down in order to see the remaining content:

Actitity with scrolling set to the bottom
Android activity - scrolling set to the bottom

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:

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:

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:

HeaderFooterActivity.java

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.

Related Articles

Comments

About the author
Gonçalo Marques is a Software Engineer with several years of experience in software development and architecture definition. During this period his main focus was delivering software solutions in banking, telecommunications and governmental areas. He created the Bytes Lounge website with one ultimate goal: share his knowledge with the software development community. His main area of expertise is Java and open source.

GitHub profile: http://github.com/gonmarques

He is also the author of the WiFi File Browser Android application: