Flex 4.5 Mobile Application Development – Controlling the visibility of the ActionBar and Tabs

May 23, 2011By 15 Comments

If you’re working on a Flex mobile application and find that you need hide the ActionBar or Tabs in the case of a TabbedViewNavigatorApplication to offer more screen space for a particular view, or based on a user’s preferences or whatever, I created a quick post to show how it can be done.

There are actually two properties available on the View class to allow you to do this: actionBarVisible and tabBarVisible. I created a simple TabbedViewNavigatorApplication to illustrate how they can be used. There are three Views in my code, but on the first view I decided to add buttons to toggle the visibility of the actionBar and tabBar. When switching between views whether via the tabs or programmatically, the visibility of those items is only affected on View 1. The View1 code is shown below:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:s="library://ns.adobe.com/flex/spark" title="View1">
	
	<fx:Script>
		<![CDATA[
			protected function onActionBarClickHandler(event:MouseEvent):void
			{
				if (actionBarVisible)
				{
					this.actionBarVisible = false;
					b.label="Show ActionBar";
				}
				else {
					this.actionBarVisible = true;
					b.label="Hide ActionBar";
				}
			}
			
			protected function onTabBarClickHandler(event:MouseEvent):void
			{
				if (tabBarVisible)
				{
					this.tabBarVisible = false;
					b2.label="Show TabBar";
				}
				else {
					this.tabBarVisible = true;
					b2.label="Hide TabBar";
				}
			}
		]]>
	</fx:Script>
	<s:VGroup width="100%" height="100%" horizontalAlign="center" top="50">
		<s:TextArea text="This is View 1" editable="false"/>
		<s:HGroup>
			<s:Button id="b" label="Hide ActionBar" click="onActionBarClickHandler(event)"/>
			<s:Button id="b2" label="Hide TabBar" click="onTabBarClickHandler(event)"/>	
		</s:HGroup>
	</s:VGroup>  
</s:View>

And here are some screenshots showing how it works when the different buttons are clicked:

Both ActionBar and TabBar Visible

ActionBar Hidden

ActionBar and TabBar Hidden

View 2 Unaffected

Below is the main application MXML code for my example:

<?xml version="1.0" encoding="utf-8"?>
<s:TabbedViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
								  xmlns:s="library://ns.adobe.com/flex/spark">	
	<s:ViewNavigator label="View1" width="100%" height="100%" firstView="views.View1"/>
	<s:ViewNavigator label="View2" width="100%" height="100%" firstView="views.View2"/>
	<s:ViewNavigator label="View3" width="100%" height="100%" firstView="views.View3"/>
</s:TabbedViewNavigatorApplication>

Filed in: Flash Builder 4.5Flex 4.5Flex 4.5/Mobile Tags:

About the Author ()

Comments (15)

Trackback URL | Comments RSS Feed

  1. Jerry says:

    Works with:
    TabbedViewNavigatorApplication
    ViewNavigatorApplication

    but not with:
    Application (using a ViewNavigator)

    Any clues to get it to work?

    • Tangent says:

      I am experiencing the same issue with the latest AIR 3.1.

      As you describe, when I use Application as the container, then embeds the “ViewNavigator”, the ActionBar cannot be turned invisible, even with forceful code like navigator.actionBar.visible = false

      The only way I could get around this is to employ a skin for the ViewNavigator, have the skin inherits ViewNavigatorSkin, override the createChidren, and have removeChild(actionBar) immediately after super.createChildren();

      Adobe, please look into this issue.

  2. This code is very useful. I hope it is work correctly. Your post is very well explained and easy to understand though the visual display.

  3. Hi,
    I’ve been trying to hide just 1 tab. I basically want my home view to not have a link in the tab bar. Is this at all possible?
    Thanks

    • Hi Brad, one way to do it would be to update the layout that is used by the tab bar skin to not include that first tab element in the layout. It will still show your home view, which I assume you still want, but not the tab for it. You’ll need to locate two classes in the Flex 4.5 SDK and copy them into your mobile project to override the defaults used. First you need to find the TabbedViewNavigatorTabBarSkin.as class, located in the SDK at: …/Adobe Flash Builder 4.5/sdks/4.5/frameworks/projects/mobiletheme/src/spark/skins/mobile/ folder and copy it into your project under a skins folder for instance, and change the package name to match yours. You also need to set that skin class to be used for your tab bar in your CSS, such as:

      s|TabbedViewNavigator #tabBar
      {
      skinClass: ClassReference(“skins.TabbedViewNavigatorTabBarSkin”);
      }

      Then, the default layout used by the tab bar is the TabbedViewNavigatorTabBarHorizontalLayout class (located in …/Adobe Flash Builder 4.5/sdks/4.5/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses), so you can copy that one too and change the package name to your local project. In there, you want to update the measure() method to check for the index of 0 element (the first tab), and set the includeInLayout to false. So your method would look like this:

          override public function measure():void
          {
              super.measure();
              
              var layoutTarget:GroupBase = target;
              if (!layoutTarget)
                  return;
              
              var elementCount:int = 0;
              
              var width:Number = 0;
              var height:Number = 0;
              
              var count:int = layoutTarget.numElements;
              for (var i:int = 0; i < count; i++)
              {
      		var layoutElement:ILayoutElement = layoutTarget.getElementAt(i);
      		if (i==0)
                         layoutElement.includeInLayout=false;
      				
      			if (!layoutElement || !layoutElement.includeInLayout)
                      continue;
                  
                  width += layoutElement.getPreferredBoundsWidth();
                  elementCount++;
                  height = Math.max(height, layoutElement.getPreferredBoundsHeight());
              }
              
              layoutTarget.measuredWidth = width;
              layoutTarget.measuredHeight = height;
          }
          

      Lastly, make sure your custom tab bar skin class you copied uses this version of the layout class instead (so in your TabbedViewNavigatorTabBarSkin, point to your local copy of your TabbedViewNavigatorTabBarHorizontalLayout).

      It may sound more complicated than it actually is, I tried to include all steps and details :)! It should take 10 minutes or less to copy the files in and make those few line changes, so hopefully that works for you!!
      Holly

      • Noah Scales says:

        Hi, Holly.

        I tried copying down the classes and creating a css file entry referencing my skin class (changes to this file do show in my GUI), with:

        s|TabbedViewNavigator#tabBar
        {
        skinClass:ClassReference(“survey.TabbedViewNavigatorTabBarSkin”);
        }

        and in addition, the local class points to the local package copy of the layout class:

        var tabLayout:survey.TabbedViewNavigatorTabBarHorizontalLayout =
        new TabbedViewNavigatorTabBarHorizontalLayout();

        and the code of the layout skin class has been changed:

        //added line below to remove Survey skin class’s first element
        if (i==0) layoutElement.includeInLayout=false;

        The code compiles fine, the tab bar shows the first element, numerous changes to break the layout class failed to show any difference, obviously the layout code changes have no effect because the local layout skin class is not being used.

        If I rename the navigator skin class and rename it back, I get the message that another file exists with the same short name. So I see I have not done something right.

        One note:
        I found that copying down the layout skin class was not all, the IDE complained until I imported the spark ButtonBarSkin class at the top of my tabbar skin class.

        Bringing that class down did no good, just created more files to import.

        I expect I’m missing something obvious here, and will appreciate any help you can give me, I’m using Flash Builder premium 4.6.

        -Noah

  4. wow, thanks for your thoughtful and detailed response. I’m glad I checked back today. Gonna give this a whirl, thank you so much!

  5. Mike says:

    Holly hi,
    great tutorial on skinning the tab bar.
    i’m trying to do the same with the default ActionBarSkin for the action bar in order to set a background image for it with no success- not much samples on the web also.
    have you tried it before?

  6. @mike,
    did you figure that out? I’m trying to add an image to actionBar bg as well, but nothing is working. I”ve tried several things inside my drawBackground override but nothing seems to work.

  7. FB says:

    The issue I have with this is that all though the tabbarvisible property does work it seems to still occupy the space. I would like to recover the bottom screen space for one page. Is there a way to hide or remove it for one page?

    Thank You for any responses

  8. Glenn says:

    Hey holly,

    Like your posts! Was wondering though if you can help out with a lil problem I’ve been having so far. I’m trying to get my custom buttons to work in or as a tabbar. Any suggestions?

    Thanks, Glenn

  9. Francisco Rodriguez says:

    Is it possible having a Mobile Flex View-based application and inside a view with tabs ?
    Thanks a lot.
    BR,

  10. Sumit says:

    Hi Holly,

    Your posts help me a lot. One more thing i want to ask you, how to manage the visibility of tab bar? i am using flex 4.6 sdk.In my application I am using 2 different tab bar.Each contain 3 tabs. Each tab page contain link to another view. but after clicking on that link i am not wish to see that tab bar in another view. Even though i moved back my tab bar is visible in my previous page also. i also unable to handle both tab bar visibility simultaneously. Is there any way to solve this?

    Thanks
    Sumit

  11. Platanote says:

    the effect in Flash Builder 4.5 with:

    navigator.hideActionBar();

    is, in Flash Builder 4.6:

    navigator.actionBar.visible=false;
    navigator.actionBar.includeInLayout=false;

Leave a Reply