User Interface Action Bar
The article describes how to use the ActionBar component in a
non-Angular NativeScript application as well as some iOS and
Android specifics. All described scenarios are demonstrated with
the appropriate code snippet. The ActionBar
is the
NativeScript common abstraction over the Android ActionBar and
iOS NavigationBar.
Defining The ActionBar
Here is how to define the ActionBar inside your page:
<Page xmlns="http://schemas.nativescript.org/tns.xsd">
<Page.actionBar>
<ActionBar title="My ActionBar"/>
</Page.actionBar>
<!-- Page content ... -->
</Page>
We will include only the ActionBar
tag in the rest
of the code-snippets in this article.
Title
Setting The Title Text
Use the title
property of the
ActionBar
to set the title:
<ActionBar title="Application Title"></ActionBar>
The result is:
Using a Custom Title View
You can set a custom title view, which will render instead of
the title. The example below shows how to combine an image and
label for a titleView
(the example contains only
the ActionBar
definition):
How to create custom title view instead of the ActionBar title.
<ActionBar title="test">
<StackLayout orientation="horizontal"
ios:horizontalAlignment="center"
android:horizontalAlignment="left">
<Image src="res://nativescript_logo" class="action-image"></Image>
<Label text="ativeScript" class="action-label"></Label>
</StackLayout>
</ActionBar>
.action-image {
width: 40;
height: 40;
vertical-align: center;
}
.action-label {
color: #3C5AFD;
font-size: 24;
font-weight: bold;
vertical-align: center;
}
The result is:
Note: You can use CSS to style the elements inside the
titleView
.
Using Custom View in Action Items
You could set a custom view, which will be rendered instead of the ActionItem text. The example below demonstrates, how to load to separate labels inside the item.
<Page>
<Page.actionBar>
<ActionBar>
<ActionBar.actionItems>
<ActionItem>
<ActionItem.actionView>
<StackLayout orientation="horizontal">
<Label text="Green" color="green"/>
<Label text="Red" color="red"/>
</StackLayout>
</ActionItem.actionView>
</ActionItem>
</ActionBar.actionItems>
</ActionBar>
</Page.actionBar>
...
</Page>
Setting the App Icon for Android
You can set the application icon only for Android. By default,
the application icon is hidden. You can show it by setting the
android.iconVisibility
property to
always
.
<ActionBar title="App Icon Demo" android.icon="res://icon" android.iconVisibility="always"></ActionBar>
The result is:
Navigation Button
The NavigationButton
component is a common
abstraction over the iOS back button and the Android navigation
button.
<ActionBar title="App Icon Demo">
<NavigationButton text="Go Back" android.systemIcon="ic_menu_back" tap="onNavBtnTap"/>
</ActionBar>
export function onNavBtnTap() {
// This code will be called only in Android.
console.log("Navigation button tapped!");
}
export function onNavBtnTap(){
// This code will be called only in Android.
console.log("Navigation button tapped!");
}
The result is:
iOS Specifics
The default text of the button is the title of the previous
page; you can change it by setting the
text
property as shown in the example
Setting the Text Title. In
iOS, the back button is used explicitly for navigation. It
navigates to the previous page and you cannot handle the
tap
event to override this behavior.
If you want to place a button on the left side of the
ActionBar
and handle the tap event (e.g., show
slide-out), you can use ActionItem
with
ios.position="left"
.
Android Specifics
In Android, you cannot set text inside the navigation button.
You can use the icon
property to set an image
(e.g., ~\images\nav-image.png
or
res:\\ic_nav
). You can use
android.systemIcon
to set one of the system icons
available in Android. In this case, there is no default
behaviour for NavigationButton's tap
event, and we
should define manually the callback function, which will be
executed.
Action Items
You can define additional action buttons using the
actionItems
collection:
<ActionBar title="Action Items">
<ActionItem tap="onShare"
ios.systemIcon="9" ios.position="left"
android.systemIcon="ic_menu_share" android.position="actionBar"></ActionItem>
<ActionItem tap="onDelete"
ios.systemIcon="16" ios.position="right"
text="delete" android.position="popup"></ActionItem>
</ActionBar>
export function onShare(args) {
console.log("Share action item tapped.");
}
export function onDelete(args) {
console.log("Delete action item tapped.");
}
export function onShare(args: observable.EventData) {
console.log("Share action item tapped.");
}
export function onDelete(args: observable.EventData) {
console.log("Delete action item tapped.");
}
The result is:
Positioning
The following positioning options are available for iOS and Android.
Android (set with android.position
):
-
actionBar
[default]: Puts the item in the ActionBar. Action item can be rendered both as text or icon. -
popup
: Puts the item in the options menu. Items will be rendered as text. -
actionBarIfRoom
: Puts the item in the ActionBar if there is room for it. Otherwise, puts it in the options menu.
iOS (set with ios.position
):
-
left
[default]: Puts the item on the left side of the ActionBar. -
right
: Puts the item on the right side of the ActionBar.
Setting Icons
You can use the icon
property to set an image
instead of text for the action item. You can use local image
(e.g., ~/images/add.png
) or resource (e.g.,
res://ic_add
). Because there is no way to
explicitly set width
and height
for
icons, the recommended approach is using resources.
You can use the android.systemIcon
and
ios.systemIcon
properties to show system icons. If
you define a system icon, it will be used instead of
icon
and text
properties.
Values for android.systemIcon
correspond to the
resources names of the built-in Android system icons. For a full
list of Android drawable names, you may visit
Android Developer Site.
Values for ios.systemIcon
are numbers from the
UIBarButtonSystemItem
enumeration:
Value | Icon | Value | Icon | |
---|---|---|---|---|
0 | Done | 12 | Search | |
1 | Cancel | 13 | Refresh | |
2 | Edit | 14 | Stop | |
3 | Save | 15 | Camera | |
4 | Add | 16 | Trash | |
5 | FlexibleSpace | 17 | Play | |
6 | FixedSpace | 18 | Pause | |
7 | Compose | 19 | Rewind | |
8 | Reply | 20 | FastForward | |
9 | Action | 21 | Undo | |
10 | Organize | 22 | Redo | |
11 | Bookmarks | 23 | PageCurl |
How To
Showing or Hiding the ActionBar
You can explicitly control the visibility of the
ActionBar
by setting the
actionBarHidden
property of the Page
.
Hidng the ActionBar
via XML.
<Page actionBarHidden="true" loaded="onPageLoaded">
</Page>
Hidng the ActionBar
via code-behind (TypeScript).
export function onPageLoaded(args: EventData) {
const page = <Page>args.object;
page.actionBarHidden = true;
}
In Android, the application bar is visible by default and shows the name of the application as title. The navigation button is visible only when it is explicitly defined in the application.
In iOS, if the application bar is empty (e.g., no title or action items are defined), it is hidden on the first page and automatically shown after navigation to host the navigation button. If the ActionBar is not empty (e.g., there is a title or action items defined) it will be shown on first page, too.
Hiding Action Items
You can use the visibility
property of the
ActionItem
to dynamically hide and show items. You
can also use binding for the visibility.
Here is an example of showing different action items when the app is in "editing" mode:
<ActionBar title="Action Items Visibility">
<ActionItem tap="onEdit" ios.systemIcon="2" android.systemIcon="ic_menu_edit" ios.position="right"
visibility="{{ isEditing ? 'collapse' : 'visible' }}"/>
<ActionItem tap="onSave" ios.systemIcon="3" android.systemIcon="ic_menu_save" ios.position="right"
visibility="{{ isEditing ? 'visible' : 'collapse' }}"/>
<ActionItem tap="onCancel" ios.systemIcon="1" android.systemIcon="ic_menu_close_clear_cancel"
visibility="{{ isEditing ? 'visible' : 'collapse' }}"/>
</ActionBar>
import { Observable } from "@nativescript/core";
export function onLoaded(args) {
var page = args.object;
page.bindingContext = new Observable();
page.bindingContext.set("isEditing", false);
}
export function onEdit(args) {
console.log("Edit item tapped.");
var btn = args.object;
btn.bindingContext.set("isEditing", true);
}
export function onSave(args) {
console.log("Save item tapped.");
var btn = args.object;
btn.bindingContext.set("isEditing", false);
}
export function onCancel(args) {
console.log("Cancel item tapped.");
var btn = args.object;
btn.bindingContext.set("isEditing", false);
}
import { Observable, View, EventData } from "@nativescript/core";
export function onLoaded(args: EventData) {
let page = <View>args.object;
page.bindingContext = new Observable();
page.bindingContext.set("isEditing", false);
}
export function onEdit(args: EventData) {
console.log("Edit item tapped.");
let btn = <view.View>args.object;
btn.bindingContext.set("isEditing", true);
}
export function onSave(args: EventData) {
console.log("Save item tapped.");
let btn = <view.View>args.object;
btn.bindingContext.set("isEditing", false);
}
export function onCancel(args: EventData) {
console.log("Cancel item tapped.");
let btn = <view.View>args.object;
btn.bindingContext.set("isEditing", false);
}
The result is:
Styling
The ActionBar has some CSS styling limitations. You can use only
background-color
and color
properties.
Here is an example:
<ActionBar title="ActionBar Style">
<NavigationButton text="Go Back" android.systemIcon="ic_menu_back"></NavigationButton>
<ActionItem ios.systemIcon="2" android.systemIcon="ic_menu_edit" ios.position="right"></ActionItem>
</ActionBar>
ActionBar {
background-color: #3C5AFD;
color: white;
}
The result is:
In iOS, the color
property affects the color of the
title and the action items. In Android, the
color
property affects only the title text.
However, you can set the default color of the text in the action
items by adding an actionMenuTextColor
item in the
Android theme (inside
App_Resources\Android\values\styles.xml
).
Note: Setting other CSS properties (e.g.,
font-family
) will only affect the views defined insidetitleView
.
Creating SideDrawer Button
This example shows how to implement a "show side-drawer button" functionality.
For Android, this example uses the
NavigationButton
because
ActionItems
are shown on the right side of the
ActionBar
.
For iOS, this code adds a regular ActionItem
with
position
set to left
. Using the
NavigationButton
as a side-drawer button in iOS is
not possible, because its function is to always navigate back in
the application.
Note: The
<android>
and<ios>
tags are used inside the XML to define platform-specific elements. Important: The platform specific tags (<android>
and<ios>
) will work only in non-Angular based project.
<ActionBar title="SideDrawer Button">
<android>
<NavigationButton icon="res://ic_menu" tap="showSideDrawer" />
</android>
<ios>
<ActionItem icon="res://ic_menu" ios.position="left" tap="showSideDrawer" />
</ios>
</ActionBar>
export function showSideDrawer(args) {
console.log("Show SideDrawer tapped.");
// Show sidedrawer ...
}
export function showSideDrawer(args: observable.EventData) {
console.log("Show SideDrawer tapped.");
// Show sidedrawer ...
}
ActionBar {
background-color: #3C5AFD;
color: white;
}
The result is: