flex 4 tabbar - disable tab

2019-05-07 19:32发布

问题:

is there a common way to disable a tab of a spark tabbar component in flex 4? with the mx tabnavigator component you can just disable the content corresponding to the tab and the tab is also disabled then. but doing this with the spark tab bar component disables just the content not the tab.

here is my simple example:

    <mx:TabNavigator x="122" y="155" width="200" height="200">
    <s:NavigatorContent label="Tab 1" width="100%" height="100%">
        <s:Label text="Label1"/>
    </s:NavigatorContent>
    <s:NavigatorContent label="Tab 2" width="100%" height="100%" enabled="false">
        <s:Label text="Label2"/>
    </s:NavigatorContent>
    <s:NavigatorContent label="Tab 3" width="100%" height="100%">
    </s:NavigatorContent>
</mx:TabNavigator>
<s:TabBar x="368.7" y="100.35" dataProvider="{viewstack1}" />
<mx:ViewStack x="364" y="133" id="viewstack1" width="200" height="200">
    <s:NavigatorContent label="Tab 1" width="100%" height="100%">
        <s:Label text="Label1"/>
    </s:NavigatorContent>
    <s:NavigatorContent label="Tab 2" width="100%" height="100%" enabled="false">
        <s:Label text="Label2"/>
    </s:NavigatorContent>
    <s:NavigatorContent label="Tab 3" width="100%" height="100%">
        <s:Label text="Label3" x="1" y="0"/>
    </s:NavigatorContent>
</mx:ViewStack>

many thx, florian

回答1:

Addendum: Literally two minutes after I got back to actually working, I found an "elegant" solution using a skin.

If you apply a custom skinClass to your tab bar you can bind the tab.enabled property just like you'd expect/want.

<fx:Script>
    <![CDATA[
[Bindable] private var tab2IsReady:Boolean = false;

private function checkCriteria():void{
    tab2IsReady = 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>

When you type "skinClass" use the auto complete to generate (in FlashBuilder ~4.5+???) 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/> in the ViewStack with its enabled property set or bound will do exactly what you expect (be enabled when true, & disabled when false).



回答2:

One solution to try would be to use mx:VBox components instead of s:NavigatorContent.

From http://blog.flexexamples.com/2007/08/25/enabling-and-disabling-specific-tabs-in-a-tabbar-control/ :

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/25/enabling-and-disabling-specific-tabs-in-a-tabbar-control/ -->
<mx:Application name="TabBar_enabled_test"
        xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:ApplicationControlBar dock="true">
        <mx:CheckBox id="tabBarEnabled"
                label="TabBar.enabled"
                selected="true"
                width="25%" />

        <mx:CheckBox id="tab1Enabled"
                label="Tab1.enabled"
                selected="true"
                width="25%" />

        <mx:CheckBox id="tab2Enabled"
                label="Tab2.enabled"
                selected="true"
                width="25%" />

        <mx:CheckBox id="tab3Enabled"
                label="Tab3.enabled"
                selected="true"
                width="25%" />
    </mx:ApplicationControlBar>

    <mx:VBox verticalGap="0">
        <mx:TabBar id="tabBar"
                width="400"
                dataProvider="{viewStack}"
                enabled="{tabBarEnabled.selected}" />

        <mx:ViewStack id="viewStack" width="400" height="100">
            <mx:VBox id="tab1"
                    label="Tab1"
                    backgroundColor="haloGreen"
                    enabled="{tab1Enabled.selected}">
                <mx:Label text="Label 1" />
            </mx:VBox>

            <mx:VBox id="tab2"
                    label="Tab2"
                    backgroundColor="haloBlue"
                    enabled="{tab2Enabled.selected}">
                <mx:Label text="Label 2" />
            </mx:VBox>

            <mx:VBox id="tab3"
                    label="Tab3"
                    backgroundColor="haloOrange"
                    enabled="{tab3Enabled.selected}">
                <mx:Label text="Label 3" />
            </mx:VBox>
        </mx:ViewStack>
    </mx:VBox>

</mx:Application>


回答3:

For those who want an working answer for Flex 4.5 (probably Flex 4 also). I finally figured out a solution. It feels like a hack to me, but Adobe's not answering the call and it's working for me. Here's a simplified example.

<!-- component that has the the TabBar in it... -->

<fx:Script>
    <![CDATA[
//imports here

import mx.core.UIComponent;

//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.

Happy Coding =D



标签: flex tabs tabbar