Timeline¶
A timeline displays tasks and the order in which they need to be completed.
Anatomy¶
Timeline Cell Views consist of a timestamp, a node, a vertical timeline, and a clickable card that can contain a headline, description, and attribute.
Timeline Preview Cell Views consist of a timestamp, a node, a horizontal timeline, and a headline.
Timeline Views consist of a scrollable list of Timeline Cell Views displayed vertically. The cells are ordered by date and are grouped under sticky headers displaying the month. The current day is marked by a colored circle, as well as a colored line if there is no event. If there are no cells, a customizable image and message is displayed instead.
Timeline Preview Views consist of a title, a button, and a list of Timeline Preview Cell Views displayed horizontally. This list is non-scrollable and displays two cells for screen widths up to 600 dp, four cells for screen widths up to 720 dp, and six cells otherwise.
Usage¶
A Timeline Cell is used to represent an event and should lead to more details on the event upon clicking its card. A Timeline View is used to display these cells in chronological order.
A Timeline Preview Cell gives a high-level overview of an event and is not clickable. A Timeline Preview View is used to display the Preview Cells along with a See All button that should lead to the full Timeline View.
Construction¶
The recommended approach for creating a Timeline Cell is through binding
a TimelineCellData
to a TimelineCellProvider
, which will be covered
in detail in "Populating the Timeline". The rest of this section will go
over direct creation of the components.
A Timeline Cell can be created by the constructor in code:
TimelineCellView cell = new TimelineCellView(getContext());
A Timeline Cell can also be created by declaring a TimelineCellView
element in XML, like this:
<com.sap.cloud.mobile.fiori.timelineview.TimelineCellView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:headline="@string/timeline_headline"
app:headlineTextAppearance="@style/TextAppearance.Body"
app:timelinePreviewHeadlineTextAppearance="@style/TextAppearance.Body"
app:description="@string/timeline_description"
app:descriptionTextAppearance="@style/TextAppearance.Body"
app:timelineAttribute="@string/timeline_attribute"
app:timelineAttributeTextAppearance="@style/TextAppearance.Body"
app:timelineTimestampTextAppearance="@style/TextAppearance.Body"
app:timelineMonthTextAppearance="@style/TextAppearance.Body"
app:timelineTodayColor="@color/timeline_today_color"
app:timelineTodayLineColor="@color/timeline_today_line_color"
app:timelineDateFormat="@string/timeline_date_format"
app:timelineTimeFormat="@string/timeline_time_format"
app:timelineDayDateFormat="@string/timeline_day_date_format"
app:timelineMonthFormat="@string/timeline_month_format"
app:timelineButtonTextAppearance="@style/FioriButton.Flat"
app:timelineButtonBackground="@drawable/fiori_flat_btn_ripple">
</com.sap.cloud.mobile.fiori.timelineview.TimelineCellView>
The above XML declaration creates a TimelineCellView
with the following attributes of note:
app:timelineTodayColor
– The color of the circle displayed around the timestamp of the current day.app:timelineTodayLineColor
– The color of the line displayed in aTODAY
cell with no event.app:timelinePreviewHeadlineTextAppearance
– The properties of the headline text in Preview View.app:timelineButtonTextAppearance
– The properties of the text on the button for Preview View.app:timelineButtonBackground
– The properties of the background on the button for Preview View.app:timelineDateFormat
– The timestamp format when the timestamp type isDATE
.app:timelineTimeFormat
– The timestamp format when the timestamp type isTIME
.app:timelineDayDateFormat
– The timestamp format when the timestamp type isDAY_DATE
.app:timelineMonthFormat
– The format of the month text that appears inMONTH
states andPREVIEW
cells.
A Timeline can be created by the constructor in code:
TimelineView timeline = new TimelineView(getContext());
A Timeline can also be created by declaring a TimelineView
element in
XML, like this:
<com.sap.cloud.mobile.fiori.timelineview.TimelineView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:timelineEmptyDrawable="@drawable/ic_event_note_24dp"
app:timelineEmptyHeadline="@string/timeline_empty_headline"
app:timelineEmptyHeadlineTextAppearance="@style/TextAppearance.Body"
app:timelineEmptyDescription="@string/timeline_empty_description"
app:timelineEmptyDescriptionTextAppearance="@style/TextAppearance.Body">
</com.sap.cloud.mobile.fiori.timelineview.TimelineView>
The above XML declaration creates a TimelineView
with the following attributes:
app:timelineEmptyDrawable
– The image that is displayed when there are no cells.app:timelineEmptyHeadline
– The headline of the message that is displayed when there are no cells.app:timelineEmptyHeadlineTextAppearance
– The properties of the empty headline text.app:timelineEmptyDescription
– The description of the message that is displayed when there are no cells.app:timelineEmptyDescriptionTextAppearance
– The properties of the empty description text.
Fields¶
Headline¶
The headline displays a title for the event.
cell.setHeadline(R.string.headlineText);
Description¶
The description describes the event. It can display up to two lines.
cell.setDescription(R.string.descriptionText);
Attribute¶
The attribute displays the type of task or an aspect of the event.
cell.setAttribute(R.string.attributeText);
Due Date¶
The due date represents the time period of the event and consists of a start date and an end date. The Timeline will automatically create a cell for each date within the range and will order the cells by their start date. The start date will determine what is displayed in the timestamp.
cell.setDueDate("22/10/2020", "25/10/2020");
If only one date is provided, that date is assumed to be the start date as well as the end date.
cell.setDueDate("22/10/2020");
If no date is provided, the cell's start date and end date are assumed to be the current time.
The accepted date formats are: dd/MM/yyyy
, dd/MM/yyyy HH:mm
, dd-MMM-yyyy
,
dd-MMM-yyyy HH:mm
, MMM dd yyyy
, MMM dd yyyy HH:mm
Timestamp¶
The timestamp displays the date or time when the event takes place,
depending on the start date and the timestamp type. The available timestamp
types are: DATE
, DAY_DATE
, and TIME
. By default, the timestamp type
is DATE
.
The timestamp format can be customized to display different date formats.
cell.setDueDate("22/10/2020 14:00");
cell.setTimestampType(TimelineCellView.TimelineCellTimestampType.DATE); // 22
cell.setDateFormat("ddd"); // 022
cell.setTimestampType(TimelineCellView.TimelineCellTimestampType.DAY_DATE); // THU\n22
cell.setDayDateFormat("EEE d"); // THU 22
cell.setTimestampType(TimelineCellView.TimelineCellTimestampType.TIME); // 2:00 PM
cell.setTimeFormat("hh:mm"); // 02:00
If consecutive cells have the same start date (YEAR
, MONTH
, DAY_OF_MONTH
),
then only the first cell in that sequence will display a timestamp. If the
consecutive cells are of type TIME
, then HOUR_OF_DAY
and MINUTE
will
be taken into account.
If there is an event on the current day and its cell is of type TIME
or DAY_DATE
, its timestamp type will be changed to DATE
.
Node¶
The node represents the state of the event. The available states are:
State | Definition |
---|---|
START |
Start date of the project timeline. |
PAST |
Completed task with a due date that has passed. |
PAST_UPCOMING |
Incomplete task with a due date that has passed. |
TODAY |
Dedicated cell for displaying the current day. The Timeline will automatically create a cell with this state if there are no events on the current day. |
DONE |
Upcoming task that has been completed. |
UPCOMING |
Upcoming task that has not been completed. |
END |
End date of the project timeline. |
MONTH |
Dedicated cell for displaying the month. The Timeline will automatically create cells with this state. |
NOT_SPECIFIED |
Default state of the cell. |
cell.setState(TimelineCellView.TimelineCellState.START);
If an event with DONE
or UPCOMING
is passed, its state will change to
PAST
or PAST_UPCOMING
, respectively.
Click Listener¶
The Timeline accepts a TimelineItemTouchListener.TimelineItemClickListener
that defines click behavior for each item.
TimelineItemTouchListener.TimelineItemClickListener listener = new TimelineItemTouchListener.TimelineItemClickListener() {
@Override
public void onCardClick(@NonNull View view, int position) {
Toast.makeText(getApplicationContext(), "Clicked on card in cell #" + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onClick(@NonNull View view, int position) {
Toast.makeText(getApplicationContext(), "Clicked on cell #" + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onLongClick(@NonNull View view, int position) {
Toast.makeText(getApplicationContext(), "Long-clicked on cell #" + position, Toast.LENGTH_SHORT).show();
}
};
timeline.setClickListener(listener);
Populating the Timeline¶
The recommended approach for populating the timeline is through utilizing
the TimelineCellData
structure. The TimelineCellData
holds all the
same fields as TimelineCellView
as listed above. All of the fields are
optional, but it is recommended to at least specify the state, headline,
and due date.
TimelineCellData data = new TimelineCellData(getContext());
data.setState(TimelineCellView.TimelineCellState.START);
data.setHeadline(R.string.headlineText);
data.setDescription(R.string.descriptionText);
data.setAttribute(R.string.attributeText);
data.setTimestampType(TimelineCellView.TimelineCellTimestampType.DATE);
data.setDateFormat("d");
data.setTimeFormat("h:mm a");
data.setDayDateFormat("EEE\nd");
data.setMonthFormat("MMM");
data.setDueDate("22/10/2020", "25/10/2020");
TimelineCellView
can be added to TimelineView
by creating a
List<TimelineCellData>
and TimelineCellProvider
, like so:
List<TimelineCellData> mCellDataList = new ArrayList<>(); // member variable
TimelineView timeline = new TimelineView(getContext());
TimelineCellProvider provider = new TimelineCellProvider();
createList(); // populate mCellDataList with cell data
provider.setCellList(getContext(), mCellDataList);
timeline.setAdapter(provider);
Similarly, TimelinePreviewCellView
can be added to TimelinePreviewView
,
except without the need for a TimelineCellProvider
:
List<TimelineCellData> mCellDataList = new ArrayList<>(); // member variable
TimelinePreviewView timeline = new TimelinePreviewView(getContext());
createList(); // populate mCellDataList with cell data
timeline.setCellList(getContext(), mCellDataList);
The Timeline will automatically order the cells by due date, creating
TODAY
, MONTH
, and other cells as needed. The Timeline can be updated
at any time by calling setCellList(Context, List)
with an updated
List
.
Loading¶
Upon loading TimelineView
initially, the Timeline will display the latest
items, starting with the current day at the top. Past items can be seen
by scrolling upwards.
If there is data that still needs to be loaded, the current cells can be
displayed along with a loading indicator at the bottom by passing in the
current list of cell data and telling the TimelineCellProvider
that more
are loading:
List<TimelineCellData> mCellDataList = new ArrayList<>(); // member variable
TimelineView timeline = new TimelineView(getContext());
TimelineCellProvider provider = new TimelineCellProvider();
createList(); // populate mCellDataList with loaded cell data
provider.setIsLoading(true);
provider.setCellList(getContext(), mCellDataList);
timeline.setAdapter(provider);
The Timeline can be updated at any time by calling setCellList(Context, List)
with an updated List
, and setIsLoading(false)
should be called when
all the data is loaded.
Note
setIsLoading(boolean)
should be called before setCellList(Context, List)
for the Timeline to reflect any changes to the state of the
loading indicator.
If there are no cell data in the list passed to TimelineCellProvider
or if no TimelineCellProvider
has been set, then a customizable empty
state will be displayed.
timeline.setEmptyDrawable(R.drawable.ic_event_note_24dp);
timeline.setEmptyHeadline(R.string.emptyHeadlineText);
timeline.setEmptyDescription(R.string.emptyDescriptionText);
Customization¶
For further customization of the cells after they have been ordered, it
is possible to override TimelineCellProvider
's
onBindView(TimelineCellView, int, int)
method to handle special cases
or access methods only available to TimelineCellView
.
TimelineCellProvider provider = new TimelineCellProvider() {
@Override
public void onBindView(@NonNull TimelineCellView view, int position, int viewType) {
super.onBindView(view, position, viewType);
if (position - 1 > 0 && mOrderedCellDataList.get(position - 1).getCellType() == TimelineCellView.TimelineCellType.MARKER) {
view.setHeadline(R.string.firstEventOfMonthText);
view.setHeadlineTextAppearance(R.style.firstEventOfMonthStyle);
view.setTodayColor(R.color.todayColor);
view.setTodayLineColor(R.color.todayLineColor);
view.setStartLine(R.color.startColor);
view.setEndLine(R.color.endColor);
view.setLineSize(R.dimen.lineSize);
view.setLinePadding(R.dimen.linePadding);
}
}
};