[TIMOB-27474] NavigationBar/ActionBar parity between Android and iOS
GitHub Issue | n/a |
---|---|
Type | Improvement |
Priority | None |
Status | Open |
Resolution | Unresolved |
Affected Version/s | Release 8.2.0 |
Fix Version/s | n/a |
Components | Android, iOS |
Labels | n/a |
Reporter | Jan Vennemann |
Assignee | Jan Vennemann |
Created | 2019-10-16T14:15:05.000+0000 |
Updated | 2019-10-16T16:03:16.000+0000 |
Description
With the introduction of [NavigationWindow](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.NavigationWindow) as a cross platform component in 8.0.0 we now have some parity issues when it comes to configuring the native ActionBar/NavigationBar.
iOS
On iOS the underlying NavigationBar can easily be configured with a bunch of properties directly in the containingWindow
. Namely these are:
- leftNavButton
- leftNavButtons
- rightNavButton
- rightNavButtons
- hideBackButton
- titleControl
*Example*
<Alloy>
<TabGroup>
<Tab>
<Window class="container">
<LeftNavButton platform=ios>
<Button title="Back" onClick="closeWindow" />
</LeftNavButton>
</Window>
</Tab>
</TabGroup>
</Alloy>
Android
Android offers similar customization, but requires a completely different API. Users need to manually grab a window'sactivity
and then configure the actionBar
property. In addition the activity
also offers onCreateOptionsMenu
to create a dropdown menu that can be opened from the ActionBar. Alloy already provides some convenient elements to configure these two properties directly from within a Window
.
*Example*
<Alloy>
<Window title="My Test App">
<ActionBar id="actionbar" title="My XML Menu" onHomeIconItemSelected="doMenuClick" />
<Menu>
<MenuItem id="item1" title="Settings" onClick="openSettings" />
<MenuItem id="item2" title="Search" onClick="doSearch" />
</Menu>
<Label id="label">Welcome!</Label>
</Window>
</Alloy>
Proposed solution
We need a common abstraction of the native ActionBar/NavigationBar that allows for easy configuration on both platforms. Alloy already has some custom behavior that differs from our classic API, although it is specific to the Android ActionBar. This proposal builds upon a similar approach but with cross-platform parity in mind.ActionBar
Introduce a newactionBar
property that transparently handles the ActionBar/NavigationBar setup behind the scenes using our existing API. We should do this via our bootstrapping mechanism for a JS only solution that won't require any changes to our native core.
API proposal
interface ActionBar {
title?: string
titleView?: Ti.UI.View
navigationButton?: NavigationButton
items?: ActionItem[],
icon?: string // Android only
}
interface NavigationButton {
title?: string // iOS only
icon?: string // Android only
click?: (e: Event): void // Android only
}
interface ActionItem {
android?: ActionItemOptions<ActionItemPositionAndroid>
ios?: ActionItemOptions<ActionItemPositionIos>
click: (e: Event): void
hidden: bool
}
enum ActionItemPositionAndroid {
ActionBar = "actionBar" // Ti.Android.SHOW_AS_ACTION_ALWAYS
ActionBarIfRoom = "actionBarIfRoom" // Ti.Android.SHOW_AS_ACTION_IF_ROOM
ActionBarWithText = "actionBarWithText" // Ti.Android.SHOW_AS_ACTION_WITH_TEXT
Popup = "popup" // Ti.Android.SHOW_AS_ACTION_NEVER
CollapseActionView = "collapseActionView" // Titanium.Android.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
}
enum ActionItemPositionIos {
Left = "left"
Right = "right"
}
interface ActionItemOptions<T> {
position: T
icon: string | number
title: string
actionView: Ti.UI.View // Android only
}
Ti.UI.Window.actionBar: ActionBar;
All of the properties on ActionBar
are optional. If not set, our current default behavior is used.
Title text and view
const win = Ti.UI.createWindow();
win.actionBar.title = 'Test' // instead of win.title
In addition to setting a simple text as in the example above, users can set a custom view.
const titleView = Ti.UI.createView({ layout: 'horizontal' });
const imageView = Ti.UI.createImageView({ image: '/logo.png' });
const titleLabel = Ti.UI.createLabel({ text: 'My App', left: 5 });
titleView.add(imageView);
titleView.add(titleLabel);
win.actionBar.titleView = titleView;
Navigation button
ThenavigationButton
represents the default back navigation button to the left.
win.actionBar.navigationButton.title = 'Prev';
Android Specifics / Limitations
On Android you *cannot* set the title. However you *can* set an icon.iOS Specifics / Limitations
On iOS you can *only* change the title of the button.Action items
The available buttons / menu of the native ActionBar/Navigation can be controlled with action items.
const onSave = () => { console.log('Saved') };
const onCancel = () => { console.log('Canceled') };
win.actionBar.items = [
{
click: onSave,
android: {
title: 'Save',
icon: 'item1.png'
position: 'actionBar'
},
ios: {
icon: Titanium.UI.iOS.SystemButton.SAVE
position: 'right'
}
},
{
click: onCancel,
android: {
title: 'Cancel',
icon: 'item2.png'
position: 'actionBar'
},
ios: {
icon: Titanium.UI.iOS.SystemButton.CANCEL
position: 'left'
}
}
]
No comments