Skip to content

Object Header

Object Header is used in the object details floor plan. The recommended approach is to bind ObjectHeader together with Toolbar via a seamless background (no shadow in between). While the Toolbar stays on the top, ObjectHeader can scroll underneath the Toolbar.

Anatomy

An Object Header consists of an image, object name (headline, sub headline), additional information (tags, footnote, body), description, and KPI. See the structure on tablet (>1024 dp) below:

Object Header Anatomy

Here is the structure of Object Header on smaller screens (<1024 dp, phone or tablet portrait mode):

Object Header Anatomy

Example

Here is an example of Object Header on a tablet:

Object Header Example

On a phone, the content of Object Header will be split into different pages if necessary:

Object Header Phone Example

Usage

Object Header is used in the object details floor plan. The recommended approach is to bind ObjectHeader together with Toolbar via a seamless background (no shadow in between). While the Toolbar stays on the top, ObjectHeader can scroll underneath the Toolbar.

Construction

Object Header can be created either by the constructor in code or by declaring an ObjectHeader element in XML like this:

    <com.sap.cloud.mobile.fiori.object.ObjectHeader
        android:id="@+id/objectHeader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="?attr/actionBarSize"
        android:elevation="4dp"
        app:body="@string/object_header_body"
        app:description="@string/object_header_description"
        app:detailImage="@drawable/object_placeholder"
        app:detailImageDescription="@string/object_header_image_desc"
        app:footnote="@string/object_header_footnote"
        app:headline="@string/object_header_headline"
        app:subheadline="@string/object_header_subheadline">
    </com.sap.cloud.mobile.fiori.object.ObjectHeader>

The above XML declaration creates an ObjectHeader with the following attributes:

  • android:layout_marginTop="?attr/actionBarSize" This sets the margin top to be the action bar height. A trick to place the Object Header under the toolbar with the desired shadow and scrolling behavior.
  • android:elevation="4dp" Elevates the Object Header.
  • app:body="@string/object_header_body" Sets the body text.

See Object Header XML attributes for all the XML attributes supported by ObjectHeader.

Fields

Image

An image provides visual representation of the object and is highly recommended.

mObjectHeader.setDetailImage(R.drawable.object_placeholder);

Headline

The headline/title is the main area for text content. The headline is the only mandatory content for ObjectHeader. Headline can be specified by:

cell.setHeadline(obj.getHeadline());

Sub Headline

The sub headline is displayed under the headline and provides additional information.

cell.setSubheadline(obj.getSubheadline());

Body

The body is displayed under the sub headline and provides additional information.

cell.setBody(obj.getBody());

Tags

Tags are usually system-generated and may be used to indicate categories, types, or statuses. They use a different visual representation than plain text, and function as independent bits of information. There can be a maximum of three tags displayed in the header; if more than three are required, the information should instead be placed in the content area. Tags, body and footnote are collectively called additional information, which could be under name block (which includes headline and sub headline), or side-by-side with the name block on a tablet.

mObjectHeader.setTag(R.string.object_header_tag1, 0);
mObjectHeader.setTag(R.string.object_header_tag2, 1);
mObjectHeader.setTag(R.string.object_header_tag3, 2);
<com.sap.cloud.mobile.fiori.common.TextChip
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/object_header_tag1"
    app:layout_header_group="TAG" />

<com.sap.cloud.mobile.fiori.common.TextChip
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/object_header_tag2"
    app:layout_header_group="TAG" />

<com.sap.cloud.mobile.fiori.common.TextChip
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/object_header_tag3"
    app:layout_header_group="TAG" />

Note

app:layout_header_group="TAG" assigns the view to "TAG" group. TextChip is a simple customized TextView that comes with the SDK. You could also use any other "chip" components.

Footnote

The footnote is displayed under the body and provides additional information.

cell.setFootnote(obj.getFootnote());

Description

If a description has been defined, it will appear in regular mode only. This is typically a longer string of text than what is displayed in the title content.

cell.setDescription(obj.getSubheadline());

KPI

This could be any View or ViewGroup for you to plug into ObjectHeader. It's usually some analytics information, thus the name KPI (Key Performance Index).

View analyticsView = View.inflate(ObjectHeaderActivity.this,
        R.layout.content_object_header_detail, null);
configureDetailText(analyticsView);
mObjectHeader.setDetailView(analyticsView);
app:layout_header_group="DETAIL"

Statuses

Up to two attributes can be displayed, stacked vertically, to show attributes of the object. A status could be either text or image.

cell.setStatusColor(BaseObjectHeaderActivity.sSapUiNegativeText, 0);
cell.setStatus(R.drawable.ic_error, 0, statusDescId);

Or, in XML:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_warning_black_24dp"
    android:tint="@color/sap_ui_button_reject_border_color"
    android:contentDescription="@string/error"
    app:layout_header_group="STATUS" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/object_header_status"
    android:textColor="@color/sap_ui_button_reject_border_color"
    app:layout_header_group="STATUS" />

Note

The only difference between this and ObjectCell is that the app:layout_header_group attribute is used.

Orientation Listener

On tablets, the layout of Object Header depends on the orientation. Most of the work is handled in the initialization of Object Header. In the case where Object Header is not reinitialized upon orientation change, an OrientationEventListener should be attached like this:

mObjectHeader.setShouldAttachOrientationListener(true);

This can also be set in XML like this:

    <com.sap.cloud.mobile.fiori.object.ObjectHeader
        android:id="@+id/objectHeader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="?attr/actionBarSize"
        android:elevation="4dp"
        app:shouldAttachOrientationListener="true">
    </com.sap.cloud.mobile.fiori.object.ObjectHeader>

Toolbar Connection

To get a seamless connection between Toolbar and ObjectHeader, some tweaks must be made to Android AppBarLayout, as follows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:fitsSystemWindows="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--appbar_always_elevated makes sure AppBarLayout always has 4 dp elevation. By default it's 0 dp.-->
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stateListAnimator="@drawable/appbar_always_elevated"
        android:background="?attr/colorPrimary">

        <!--Setting titleEnabled and expandedTitleTextAppearance to get rid of title animation-->
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:expandedTitleTextAppearance="@style/TextAppearance.AppCompat.Title"
            app:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed"
            app:titleEnabled="false">

            <!--layout_marginTop must be the toolbar height. ObjectHeader and Toolbar are both
            elevated to 4 dp so there's no shadow between them.-->
            <com.sap.cloud.mobile.fiori.object.ObjectHeader
                android:id="@+id/objectHeader"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="?attr/actionBarSize"
                android:elevation="4dp"
                tools:layout_editor_absoluteY="8dp">
                ...
            </com.sap.cloud.mobile.fiori.object.ObjectHeader>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:elevation="4dp"
                android:background="?attr/colorPrimary"
                app:layout_collapseMode="pin"
                app:theme="@style/AppTheme.AppBarOverlay"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <!--layout_behavior must be used together with AppBarLayout to achieve desired scrolling effect.-->
    <android.support.v4.widget.NestedScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        ...
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

And the appbar_always_elevated state list is defined as:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <objectAnimator android:propertyName="elevation"
            android:valueTo="4dp"
            android:valueType="floatType"
            android:duration="1"/>
    </item>
</selector>

Some things to consider:

  • AppBarLayout is always elevated.
  • Title transition in CollapsingToolbarLayout should be disabled.
  • android:layout_marginTop="?attr/actionBarSize" on ObjectHeader to make sure they do not overlap when not scrolled.

Style

For further information on style, refer to the Object Cell style guide. The differences are:

  • The style reference in FioriTheme becomes objectHeaderStyle.
  • The default style is called ObjectHeader.
  • The text appearances are called TextAppearance.Fiori.ObjectHeader.Body.

API Reference

See ObjectHeader


Last update: September 1, 2020