Right, just a short code-snippet I'd like to share for those who have been searching for a solution for ages (like I have). I was looking for a way to hide specific tabs in a TabNavigator in Flex 3 without removing a child form the ViewStack.
This is not possible by simply hiding a child in the viewstack (child.hide = true) or by setting its visibility to false (child.visible = false).
With an easy workaround you can set the visiblity of a specific tab to false:
tabNavigator
.getTabAt
(1).visible
=
false;
Probably more people have found this solution, but I couldn't find it on the web so here it is.
16 comments:
That's not good solution - everybody can switch to "hidden" tabs with keyboard. :)
If that's true, what Anonymous said, I would imagine it could be easily fixed by also setting the tab to enabled = false
@Raj:
tabs.getTabAt(tabs.getChildIndex(someTab)).visible=false;
So this leaves a hole in the tab buttons (the missing tooth look) if you hide one in the middle of your tabs. Is there some way to shift all the remaining visible tabs without creating a tab manager of your own to add/remove items in a specific order?
To answer the question from 'Anon' above - to solve the "hole in the tab buttons" problem, simply add the following line of code...
tabNavigator.getTabAt(1).includeInLayout = false;
Great article
The includeInLayout was the cherry in the cake, thanks a lot!!
"hole in the tab buttons" problem solve:
tabNavigator.tabHeight = 0;
:)
combination helped
tabs.getTabAt(indx).visible = false;
tabs.getTabAt(indx).includeInLayout = false;
thanks
Thank you very much for the code.. works very well for me.
Thanks
Varad
Hello,
Is it possible to have the exactly similar behavior in an Accordion.
Thanks in advance.
Regards
Varad
For those who want an working answer to *disabling* TabBar tabs in Flex 4.5 (probably Flex 4 also). I finally figured out a solution. It feels like a hack to me, but it's working for me. Here's a simplified example. (Note: I had to add a space after each < so that the MXML would show.)
< !-- component that has the the TabBar in it... -->
< fx:Script>
< ![CDATA[
//imports here
import mx.core.UIComponent;
//other imports
private function setTabEnabled(index:int,enabled:Boolean):void{
var theTab:UIComponent = theTabBar.dataGroup.getElementAt(index) as UIComponent;
if(theTab){theTab.enabled = enabled;}
}
]]>
< /fx:Script>
< s:TabBar id="theTabBar"
dataProvider="{viewStack}"/>
< mx:ViewStack id="viewStack">
< s:NavigatorContent label="0th Tab">
< !-- ...Content -->
< /s:NavigatorContent>
< s:NavigatorContent label="1st Tab">
< !-- ...Content -->
< /s:NavigatorContent>
< s:NavigatorContent label="2nd Tab">
< !-- ...Content -->
< /s:NavigatorContent>
< /mx:ViewStack>
< !-- rest of the component that has the the TabBar in it... -->
Then you just call `setTabEnabled(theTabIndex,trueFalse)` in an event handler related to whatever decides why the tab is, or isn't, enabled.
I *should* extend the TabBar to support this, but I've already spent enough time trying to figure it out. I'm just posting this everywhere I *thought* I found the answer.
Happy Coding =D
Addendum:
Literally two minutes after I got back to actually working, I found an "elegant" solution by skinning the TabBar.
If you apply a custom skinClass to your tab bar you can bind the tab.enabled property just like you'd expect/want.
< !-- component that has the the TabBar in it... -->
< fx:Script>
< ![CDATA[
[Bindable] private var tab2IsReady:Boolean = false;
private function checkCriteria():void{
tab2IReady = someOtherThing.isFinished;//Boolean
}
]]>
< /fx:Script>
< s:TabBar id="theTabBar"
dataProvider="{viewStack}"
skinClass="skins.CustomTabBarSkin"/>
< mx:ViewStack id="viewStack">
< s:NavigatorContent label="Tab index 0">
< !-- Your first tab's content -->
< /s:NavigatorContent>
< s:NavigatorContent label="Tab index 1" enabled="{tab2IsReady}">
< !-- Your second tab's content -->
< /s:NavigatorContent>
< /mx:ViewStack>
< !-- rest of the component that has the the TabBar in it... -->
When you type "skinClass" use the auto complete to generate the custom skin (named whatever you want).
The code will appear like below (I left out the Script tag).
< ?xml version="1.0" encoding="utf-8"?>
< !-- skins/CustomTabBarSkin.mxml
...
Adobe's copyright & doc comments
...
-->
< s:Skin
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
alpha.disabled="0.5">
< fx:Metadata>
< ![CDATA[
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.TabBar")]
]]>
< /fx:Metadata>
< !-- optional Script tag here -->
< s:states>
< s:State name="normal" />
< s:State name="disabled" />
< /s:states>
< !--- @copy spark.components.SkinnableDataContainer#dataGroup -->
< s:DataGroup id="dataGroup" width="100%" height="100%">
< s:layout>
< s:ButtonBarHorizontalLayout gap="-1"/>
< /s:layout>
< s:itemRenderer>
< fx:Component>
< s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin" />
< /fx:Component>
< /s:itemRenderer>
< /s:DataGroup>
< /s:Skin>
< --End skins/CustomTabBarSkin.mxml --?
Change:
< fx:Component>
< s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin" />
< /fx:Component>
To:
< fx:Component>
< s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin"
enabled="{data.enabled}" />
< /fx:Component>
Then any < s:NavigatorContent/> with its enabled property set or bound will do exactly what you expect
(be enabled when true, & disabled when false).
This doesn't work at all for me, anyone have any code? Email to enriqueleon80@gmail.com?
Quite urgent!
Post a Comment