ActionTray

ActionTray running on an iPad

ActionTray running on an iPad

Works With:

apple_logo google_android

ActionTray

A dockable, customizable, slide-out, tray view controller for iOS and Android.


  • Multiple tray types
  • Group trays
  • Multiple dragTab Types and placement
  • Works on phones and tablets
  • Supports Android and iOS

$150$50

About ActionTray

ActionTray is a dockable, customizable, slide-out, tray view controller for iOS and Android that can be attached to the top, left, bottom or right sides of the screen. ActionTray supports three tray types:

  • Draggable - The user can drag the tray out from the edged anywhere between its open and closed positions or double tap it to snap between open and closed.
  • Popup - The tray will snap between its open and closed positions when its Drag Tab is touched
  • AutoClosingPopup - Just like the Popup tray but it will also close if the user taps its content area

Use Alone or in Groups

You can place individual ActionTrays along any edge of the screen or place several ActionTrays togehter and attach them to an ActionTrayManager to control them as a group and use them like palettes or menus. The ActionTrayManager provides events to respond to user interaction in any of the trays it controls and it automatically ensures that only one tray in the group is open at a time.

Events

ActionTray defines the following events that you can monitor and respond to:

  • Touched
  • Moved
  • Released
  • Opened
  • Closed

Appearance

ActionTray is fully customizable with user definable appearances for every element of its UI. ActionTray supports the following Drag Tab types:

  • Plain - An empty Drag Tab
  • GripOnly - A 3 line grip in the Drag Tab
  • GripAndText - A 3 line grip and a title in the Drag Tab
  • TitleOnly - Only the title in the Drag Tab
  • IconOnly - Only an icon in the Drag Tab
  • IconAndTitle - An icon and title in the Drag Tab
  • CustomDrawn - Allows for a totally custom drawn Drag Tab

You can also position where the Drag Tab appears on the ActionTray as one of the following:

  • TopOrLeft - Appears on the top or left side of the ActionTray based on its orientation
  • Middle - Appears in the middle of the ActionTray
  • BottomOrRight - Appears on the bottom or right side of the ActionTray based on its orientation
  • Custom - You can control the position of the Drag Tab by setting the tabOffset property of the ActionTray

Features

ActionTray includes a fully documented API with comments for every feature. The ActionTray user interface is drawn with vectors and is fully resolution indenpendant.

iOS Example

ActionTray was designed to make adding it to a project super easy. Start an iPad, iPhone or Universal project in Xamarin Studio and build the project. Next, double click the MyProjectViewController.xib file to open it in Xcode. Insert a UIView and place it along one of the edges of the main UIView making it a large as it will be when fully opened by the user. Next change its Class to UIActionTray and add any other views or components that will be part of the tray.

using Appracatappra.ActionComponents.ActionTray;
...

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();

    ...

    // Wireup the left side tray created in the .xib file and style
    // it to be a drag out tray.
    if (leftTray != null) {
        // Set tray type
        leftTray.orientation = UIActionTrayOrientation.Left;
        leftTray.tabLocation=UIActionTrayTabLocation.BottomOrRight;
        leftTray.frameType=UIActionTrayFrameType.EdgeOnly;
        leftTray.tabType=UIActionTrayTabType.IconAndTitle;

        // Style tray
        leftTray.appearance.background=UIColor.LightGray;
        leftTray.appearance.frame=UIColor.DarkGray;
        leftTray.icon=UIImage.FromFile ("Images/icon_calendar.png");
        leftTray.title="Events";
        leftTray.appearance.tabAlpha=0.25f;
        leftTray.CloseTray (false);

        // Respond to the tray being touched
        leftTray.Touched+= (tray) => {
            // Are we on an iPhone?
            if (UserInterfaceIdiomIsPhone) {
                //Yes, close this tray and aminate the closing
                rightTray.CloseTray (true);
            }

            // Tell any open palette trays to close
            trayManager.CloseAllTrays ();

            // Close document tray
            if (documentTray!=null) 
                documentTray.CloseTray (true);
        };
    }

    // Wireup the right tray created in the .xib file and style it
    // to be a popup tray. Touch it's dragTab to open and close it.
    if (rightTray != null) {
        // Are we on an iPhone?
        if (UserInterfaceIdiomIsPhone) {
            // Move the subview into view and attach it to the master view
            rightTray.MoveTo (new PointF(320f-rightTray.Frame.Width,0f));
            View.AddSubview(rightTray);

            // iPhone specific settings
            rightTray.tabLocation=UIActionTrayTabLocation.BottomOrRight;
        }

        // Set tray type
        rightTray.trayType=UIActionTrayType.Popup;
        rightTray.orientation=UIActionTrayOrientation.Right;
        rightTray.bringToFrontOnTouch=true;
        if (UserInterfaceIdiomIsPhone) rightTray.CloseTray(false);

        // Style the tray
        rightTray.appearance.background=UIColor.DarkGray;

        // Respond to the tray being opened
        rightTray.Opened+= (tray) => {
            //Are we on an iPhone?
            if (UserInterfaceIdiomIsPhone) {
                //Yes, close this tray and aminate the closing
                leftTray.CloseTray (true);
            }

            // Tell any open palette trays to close
            trayManager.CloseAllTrays ();

            // Close document tray
            if (documentTray!=null) 
                documentTray.CloseTray (true);
        };
    }

    ...

}

NOTE: ActionTrays and the UIViews that they control can be completely created in C# code without using .xib files.

Android Example

ActionTray was designed to make adding it to a project super easy. Start an Android project in Xamarin Studio, switch to the Android Designer and add a RelativeLayout to be the parent of the ActionTab. Add one or more Views, switch to the Source view and change their type to Appracatappra.ActionComponents.ActionTray.UIActionTray. Wire-up their functionality inside your Main Activity:

using Appracatappra.ActionComponents.ActionTray;
...

[Activity (Label = "ActionTrayTest.Android", MainLauncher = true)]
public class Activity1 : Activity
{
    #region Private Variables
    private UIActionTray leftTray, rightTray, toolsTray, propertyTray, paletteTray, documentTray;
    #endregion 

    #region Public Variables
    public UIActionTrayManager trayManager;
    #endregion

    #region Override Methods
    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

        // Set our view from the "main" layout resource
        SetContentView (Resource.Layout.Main);

        // Gain Access to all views and controls in our layout
        leftTray = FindViewById<UIActionTray> (Resource.Id.trayLeft);
        rightTray = FindViewById<UIActionTray> (Resource.Id.trayRight);
        toolsTray = FindViewById<UIActionTray> (Resource.Id.trayTools);
        propertyTray = FindViewById<UIActionTray> (Resource.Id.trayProperty);
        paletteTray = FindViewById<UIActionTray> (Resource.Id.trayPalette);
        documentTray = FindViewById<UIActionTray> (Resource.Id.trayDocuments);

        // Create a TrayManager to handle a collection of "palette"
        // trays. It will automatically close any open tray when 
        // another tray in this collection is opened.
        trayManager = new UIActionTrayManager ();

        // Automatically close the left and right trays when any tray
        // in the manager's collection is opened
        trayManager.TrayOpened += (tray) => {
            // Animate the trays being closed
            leftTray.CloseTray (true);
            rightTray.CloseTray (true);
        };

        // Setup the left side tray
        leftTray.trayType = UIActionTrayType.Draggable;
        leftTray.orientation = UIActionTrayOrientation.Left;
        leftTray.tabLocation = UIActionTrayTabLocation.BottomOrRight;
        leftTray.frameType = UIActionTrayFrameType.EdgeOnly;
        leftTray.tabType = UIActionTrayTabType.IconAndTitle;
        leftTray.bringToFrontOnTouch=true;

        // Style tray
        leftTray.appearance.background = Color.Gray;
        leftTray.appearance.border = Color.Red;
        leftTray.icon = Resource.Drawable.icon_calendar;
        leftTray.title = "Events";
        leftTray.appearance.tabAlpha=100;
        leftTray.CloseTray (false);

        // Respond to the left tray being touched
        leftTray.Touched+= (tray) => {
            //Yes, close this tray and aminate the closing
            rightTray.CloseTray (true);

            // Tell any open palette trays to close
            trayManager.CloseAllTrays ();

            // Close document tray
            documentTray.CloseTray (true);
        };

        // Setup the right side tray
        rightTray.trayType = UIActionTrayType.Popup;
        rightTray.orientation = UIActionTrayOrientation.Right;
        rightTray.bringToFrontOnTouch = true;
        rightTray.CloseTray (false);

        // Respond to the tray being opened
        rightTray.Opened+= (tray) => {
            //Close this tray and aminate the closing
            leftTray.CloseTray (true);

            // Tell any open palette trays to close
            trayManager.CloseAllTrays ();

            // Close document tray
            documentTray.CloseTray (true);
        };

        // Set tray type
        documentTray.trayType = UIActionTrayType.AutoClosingPopup;
        documentTray.orientation = UIActionTrayOrientation.Bottom;
        documentTray.tabType = UIActionTrayTabType.GripAndTitle;
        documentTray.bringToFrontOnTouch=true;

        // Style tray
        documentTray.tabWidth = 125;
        documentTray.appearance.background = Color.Gray;
        documentTray.title = "Documents";
        documentTray.CloseTray (false);

        // Respond to the tray being opened
        documentTray.Opened += (tray) => {
            // Close left and right trays
            leftTray.CloseTray(true);
            rightTray.CloseTray(true);
        };

        //--------------------------------------------------------------------------------------
        // Create three action tray's and use them as a collection via an ActionTrayManager
        //--------------------------------------------------------------------------------------

        //--------------------------------------------------------------------------------------
        // Palette 1
        // Set tray type
        paletteTray.trayType = UIActionTrayType.AutoClosingPopup;
        paletteTray.orientation = UIActionTrayOrientation.Top;
        paletteTray.tabLocation = UIActionTrayTabLocation.TopOrLeft;
        paletteTray.tabType = UIActionTrayTabType.IconAndTitle;
        paletteTray.CloseTray (false);

        // Style tray
        paletteTray.tabWidth = 125;
        paletteTray.appearance.background = Color.Gray;
        paletteTray.icon = Resource.Drawable.icon_palette;
        paletteTray.title="Palette";

        // Add this tray to the manager's collection
        trayManager.AddTray (paletteTray);

        //--------------------------------------------------------------------------------------
        // Palette 2
        // Setup property tray type
        propertyTray.trayType = UIActionTrayType.Popup;
        propertyTray.orientation = UIActionTrayOrientation.Top;
        propertyTray.tabLocation = UIActionTrayTabLocation.TopOrLeft;
        propertyTray.tabType = UIActionTrayTabType.IconAndTitle;
        propertyTray.CloseTray (false);

        // Style tray
        propertyTray.tabWidth = 125;
        propertyTray.appearance.background = Color.Rgb (38,38,38);
        propertyTray.icon=Resource.Drawable.icon_measures;
        propertyTray.title="Properties";

        // Add this tray to the manager's collection
        trayManager.AddTray (propertyTray);

        //--------------------------------------------------------------------------------------
        // Palette 3
        // Setup tools tray type
        toolsTray.trayType = UIActionTrayType.AutoClosingPopup;
        toolsTray.orientation = UIActionTrayOrientation.Top;
        toolsTray.tabType = UIActionTrayTabType.IconOnly;
        toolsTray.CloseTray (false);

        // Style tools tray
        toolsTray.tabWidth = 50;
        toolsTray.tabLocation = UIActionTrayTabLocation.BottomOrRight;
        toolsTray.appearance.background = Color.Rgb (38,38,38);
        toolsTray.icon = Resource.Drawable.icon_pencil;

        // Add this tray to the manager's collection
        trayManager.AddTray (toolsTray);
    }

    protected override void OnSaveInstanceState (Bundle outState)
    {
        //Save the state of all trays on the screen
        outState.PutString("leftTray",leftTray.SaveState);
        outState.PutString("rightTray",rightTray.SaveState);
        outState.PutString("documentTray",documentTray.SaveState);
        outState.PutString("paletteTray",paletteTray.SaveState);
        outState.PutString("propertyTray",propertyTray.SaveState);
        outState.PutString("toolsTray",toolsTray.SaveState);

        base.OnSaveInstanceState (outState);
    }

    protected override void OnRestoreInstanceState (Bundle savedInstanceState)
    {
        //Restore all trays to their previous states
        leftTray.RestoreState(savedInstanceState.GetString("leftTray"));
        rightTray.RestoreState(savedInstanceState.GetString("rightTray"));
        documentTray.RestoreState(savedInstanceState.GetString("documentTray"));
        paletteTray.RestoreState(savedInstanceState.GetString("paletteTray"));
        propertyTray.RestoreState(savedInstanceState.GetString("propertyTray"));
        toolsTray.RestoreState(savedInstanceState.GetString("toolsTray"));

        base.OnRestoreInstanceState (savedInstanceState);
    }
    #endregion 
}

Trial Version

The Trial version of ActionTray is fully functional however the background is watermarked. The fully licensed version removes this watermark.

Screenshots created with PlaceIt and may contain simulated functionality not included in the ActionTray.

ActionTray Component

Getting Started with ActionTrays

To use an ActionTray in your mobile application include the ActionPack.iOS or ActionPack.Android component and reference the following using statement in your C# code:

using Appracatappra.ActionComponents.ActionTray;

Minimal Setup Required

Whether created as a .xib file in Xcode for iOS or the designer for Android or built directly from C# code the following two properties must be set before the ActionTray is displayed:

// These values MUST be set in code before the view is displayed
tray.trayType = UIActionTrayType.Popup;
tray.orientation = UIActionTrayOrientation.Right;

Failure to set the above lines before display can result in an ActionTray that is drawn and/or behaves incorrectly.

If the tray is being created completely in C# code, set the above lines after you have set the tray's Frame size and added the tray to the parent View so that it can correctly calculate its open and closed positions.

Working with ActionTrays in Android

ActionTray was designed to make adding it to a project super easy. Start an Android project in Xamarin Studio, switch to the Android Designer and add a RelativeLayout to be the parent of the ActionTray. Add one or more Views, switch to the Source view and change their type to Appracatappra.ActionComponents.ActionTray.UIActionTray.

Note: The ActionTray MUST be hosted inside a RelativeView or it will not work correctly! The ActionTray itself is a type of RelativeLayout so add any UI Components to the tray and position them within it using RelativeLayout metrics.

Configuring an ActionTray

Aside from the base, minimal setup above, there are several features that you can use to customize not only the look but the feel of your action trays. Here is an example in iOS for an ActionTray added to a .xib file:

// Set tray type
leftTray.orientation = UIActionTrayOrientation.Left;
leftTray.tabLocation=UIActionTrayTabLocation.BottomOrRight;
leftTray.frameType=UIActionTrayFrameType.EdgeOnly;
leftTray.tabType=UIActionTrayTabType.IconAndTitle;

// Style tray
leftTray.appearance.background=UIColor.LightGray;
leftTray.appearance.frame=UIColor.DarkGray;
leftTray.icon=UIActionImage.FromFile ("Images/icon_calendar.png");
leftTray.title="Events";
leftTray.CloseTray (false);

And the same code for Android for an ActionTray created in the designer:

// Gain Access to all views and controls in our layout
UIActionTray leftTray = FindViewById<UIActionTray> (Resource.Id.trayLeft);
...

// Setup the left side tray
leftTray.trayType = UIActionTrayType.Draggable;
leftTray.orientation = UIActionTrayOrientation.Left;
leftTray.tabLocation = UIActionTrayTabLocation.BottomOrRight;
leftTray.frameType = UIActionTrayFrameType.EdgeOnly;
leftTray.tabType = UIActionTrayTabType.IconAndTitle;

// Style tray
leftTray.appearance.background = Color.Gray;
leftTray.appearance.border = Color.Red;
leftTray.icon = Resource.Drawable.icon_calendar;
leftTray.title = "Events";
leftTray.appearance.tabAlpha=100;
leftTray.CloseTray (false);

Responding to User Interaction

ActionTrays define several events that can be responded to such as Touched, Moved, Released, Opened, Closed or CustomDrawDragTab. The following is an example of handling an ActionTray being opened on either iOS or Android:

// Respond to the tray being opened
rightTray.Opened+= (tray) => {
    // Tell any open palette trays to close
    trayManager.CloseAllTrays ();
};

Working with Groups of ActionTrays

ActionTray provides a UIActionTrayManager to make working with groups of ActionTrays easier. The UIActionTrayManager ensures that only one tray in the group is open at any given time and provides events for handling the trays it controls as a group. The following is an example of building a UIActionTrayManager and responding to any tray being opened in the group for both iOS and Android:

// Create a TrayManager to handle a collection of "palette"
// trays. It will automatically close any open tray when 
// another tray in this collection is opened.
trayManager = new UIActionTrayManager ();

// Automatically close the left tray when any tray
// in the manager's collection is opened
trayManager.TrayOpened += (tray) => {
    // Animate the tray being closed
    leftTray.CloseTray (true);
};

Configure your ActionTrays as normal and use the following code to add them to the Tray Managers collection. The tray will be automatically close by the manager when added:

// Add this tray to the manager's collection
trayManager.AddTray (paletteTray);

Custom Drawing the DragTab

ActionTrays provide several types of built in dragTabs and many properties for controlling their appearance. Sometimes, however, that isn't enough. That's why ActionTrays allow you to custom draw the dragTab by hand. Here is an example in iOS:

// Set tray type
toolsTray.trayType=UIActionTrayType.AutoClosingPopup;
toolsTray.tabType=UIActionTrayTabType.IconOnly;
toolsTray.tabType=UIActionTrayTabType.CustomDrawn;
toolsTray.CloseTray (false);

// Style tray
toolsTray.tabWidth=50f;
toolsTray.appearance.background=UIColor.FromRGB (38,38,38);

// Custom draw the tray's drag tab
toolsTray.CustomDrawDragTab+= (tray, rect) => {
    // Mix background color
    UIColor tabColor;

    if (tray.frameType==UIActionTrayFrameType.None) {
        tabColor=tray.appearance.background.ColorWithAlpha (tray.appearance.tabAlpha);
    } else {
        tabColor=tray.appearance.frame.ColorWithAlpha (tray.appearance.tabAlpha);
    }

    // Save current context
    var context = UIGraphics.GetCurrentContext();

    // Draw tab in the given bounds
    var bodyPath = UIBezierPath.FromRect(rect);
    tabColor.SetFill();
    bodyPath.Fill();

    // Draw icon
    var icon=UIImage.FromFile ("Images/icon_pencil.png");
    var y=rect.GetMinY()+5f;
    var tabIconRect = new RectangleF(rect.GetMinX() + 1, y, 30, 30);
    var tabIconPath = UIBezierPath.FromRect(tabIconRect);
    context.SaveState();
    tabIconPath.AddClip();
    icon.Draw(new RectangleF((float)Math.Floor(tabIconRect.GetMinX() + 1f), (float)Math.Floor(y + 0.5f), icon.Size.Width, icon.Size.Height),CGBlendMode.Normal,tray.appearance.tabAlpha);
    context.RestoreState();
};

Here is the same example in Android:

// Setup tools tray type
toolsTray.trayType = UIActionTrayType.AutoClosingPopup;
toolsTray.orientation = UIActionTrayOrientation.Top;
toolsTray.tabType = UIActionTrayTabType.IconOnly;
toolsTray.CloseTray (false);

// Style tools tray
toolsTray.tabWidth = 50;
toolsTray.tabLocation = UIActionTrayTabLocation.BottomOrRight;
toolsTray.appearance.background = Color.Rgb (38,38,38);
toolsTray.tabType = UIActionTrayTabType.CustomDrawn;
toolsTray.icon = Resource.Drawable.icon_pencil;

// Custom draw this tab
toolsTray.CustomDrawDragTab += (tray, canvas, rect) => {
    //Draw background
    var body= new ShapeDrawable(new RectShape());
    body.Paint.Color=tray.appearance.background;
    body.SetBounds (rect.Left, rect.Top, rect.Right, rect.Bottom);
    body.Draw (canvas);

    //Define icon paint
    var iPaint=new Paint();
    iPaint.Alpha=tray.appearance.tabAlpha;

    //Load bitmap
    var bitmap=BitmapFactory.DecodeResource(Resources,tray.icon);

    //Draw image
    canvas.DrawBitmap (bitmap, rect.Left+1, rect.Top+5, iPaint);
};

Maintain State on Android

Since views are destroyed and recreated on Android devices for events such as screen rotation, ActionTrays provide methods for saving and restoring their state. Here is an example:

protected override void OnSaveInstanceState (Bundle outState)
{
    //Save the state of all trays on the screen
    outState.PutString("leftTray",leftTray.SaveState);
    outState.PutString("rightTray",rightTray.SaveState);
    outState.PutString("documentTray",documentTray.SaveState);
    outState.PutString("paletteTray",paletteTray.SaveState);
    outState.PutString("propertyTray",propertyTray.SaveState);
    outState.PutString("toolsTray",toolsTray.SaveState);

    base.OnSaveInstanceState (outState);
}

protected override void OnRestoreInstanceState (Bundle savedInstanceState)
{
    //Restore all trays to their previous states
    leftTray.RestoreState(savedInstanceState.GetString("leftTray"));
    rightTray.RestoreState(savedInstanceState.GetString("rightTray"));
    documentTray.RestoreState(savedInstanceState.GetString("documentTray"));
    paletteTray.RestoreState(savedInstanceState.GetString("paletteTray"));
    propertyTray.RestoreState(savedInstanceState.GetString("propertyTray"));
    toolsTray.RestoreState(savedInstanceState.GetString("toolsTray"));

    base.OnRestoreInstanceState (savedInstanceState);
}

Examples

For full examples of using ActionTrays in your mobile application please see the APTest.iOS example app included with this component. ActionTrays are used throughout the app.

The APTest.iOS app not only includes this documentation but it also includes the full API documentation for the entire ActionPack component suite.

See the API documentation for ActionTray for a complete list of features and their usage.

Trial Version

The Trial version of ActionTray is fully functional however the background is watermarked. The fully licensed version removes this watermark.

ActionTray for iOS

You can find the full API documentation for ActionTray iOS here:

http://appracatappra.com/api/ios/

 

ActionTray for Android

You can find the full API documentation for ActionTray Android here:

http://appracatappra.com/api/android/

At Appracatappra we take quality very seriously and always strive to provide the easiest to use and most trouble free Xamarin Studio Components available.

If you are experiencing an issue with one of our components or have a question about it's usage please either visit our support forum or fill out the request form below:

Your Name (required)

Your Email (required)

Subject

Component:

Device:

iPhone/iPod TouchiPadAndroid PhoneAndroid Tablet

OS Version:

Type:

Question/Issue

Verification:

captcha

Please enter the text above: