Uploaded image for project: 'Titanium SDK/CLI'
  1. Titanium SDK/CLI
  2. TIMOB-27474

NavigationBar/ActionBar parity between Android and iOS

    Details

    • Type: Improvement
    • Status: Open
    • Priority: None
    • Resolution: Unresolved
    • Affects Version/s: Release 8.2.0
    • Fix Version/s: None
    • Component/s: Android, iOS
    • Labels:
      None

      Description

      With the introduction of 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 containing Window. 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's activity 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 new actionBar 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

      The navigationButton 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'
          }
        }
      ]
      

        Attachments

          Activity

            People

            • Assignee:
              jvennemann Jan Vennemann
              Reporter:
              jvennemann Jan Vennemann
            • Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:

                Backbone Issue Sync

                • Backbone Issue Sync is enabled for your project, but we do not have any synchronization info for this issue.

                  Git Source Code