brybam
brybam

Reputation: 5019

How to move Flex Mobile ActionBar down just a little bit?

I'm trying to simply move the actionBar down 75 pixels so I can squeeze an adMob ad in there.

I tried:

navigator.actionBar.y=75;

But, i'm not seeing anything different visually, it's not moving, it's giving me no errors, but if i do trace(navigator.actionBar.y); it claims it's at 75....even though it's clearly not on the screen.

Does anyone have any ideas? Also, this would only be for ONE view, I can't use a solution that would move the action bar down throughout the entire application. I just need it moved down in THIS particular view.

Thanks!

EDIT: @Brian, Thanks for the suggestion, almost done this whole mess. I'm trying to make a function inside the skin to add the space for the adMob ad. But, I don't think im referencing the function correctly, because when i do it im not getting any errors, and nothing is happening.

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" >
    <!-- host component -->
    <fx:Metadata>
        [HostComponent("spark.components.ViewNavigator")]
    </fx:Metadata>
    <fx:Script>
        <![CDATA[

            public function adMobVisible(trueOrFalse:Boolean):void
            {
                if(trueOrFalse)
            {
                main_group.top=70;
            }
            else
            {
                main_group.top=0;
            }
            }

        ]]>
    </fx:Script>

    <!-- states -->
    <s:states>
        <s:State name="landscapeAndOverlay" />
        <s:State name="portraitAndOverlay" />
        <s:State name="landscape" />
        <s:State name="portrait" />
        <s:State name="disabled" />
        <s:State name="normal" />
        <!-- <s:State name="admob" /> -->
    </s:states>

    <s:VGroup id="main_group" width="100%" height="100%">
        <s:ActionBar id="actionBar" width="100%" />
        <s:Group id="contentGroup" width="100%" height="100%" />
    </s:VGroup>
</s:Skin>

I did:

import skins.AdMobHolderSkin;

protected var ad:AdMobHolderSkin = new AdMobHolderSkin();

up top... then I just tried to do a simple thing like:

ad.adMobVisible(true);

But nothing happens. Any ideas? Thanks for helping with this.

Upvotes: 1

Views: 1160

Answers (1)

Brian Genisio
Brian Genisio

Reputation: 48137

If you inspect the code for ViewNavigatorSkin, you will find that it lays out its two items (ActionBar and Group) using simple math. In other words, it is not using a layout container in which setting top or y will have any effect.

Instead, you need to skin the ViewNavigator. First, define the skin (notice how I set the top="75" in the VGroup :

VNSkin.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark">
    <!-- host component -->
    <fx:Metadata>
        [HostComponent("spark.components.ViewNavigator")]
    </fx:Metadata>

    <!-- states -->
    <s:states>
        <s:State name="landscapeAndOverlay" />
        <s:State name="portraitAndOverlay" />
        <s:State name="landscape" />
        <s:State name="portrait" />
        <s:State name="disabled" />
        <s:State name="normal" />
        <s:State name="moved" />
    </s:states>

    <s:VGroup width="100%" height="100%" top="0" top.moved="75">
        <s:ActionBar id="actionBar" width="100%" />
        <s:Group id="contentGroup" width="100%" height="100%" />
    </s:VGroup>
</s:Skin>

Then, inside of my main application, I will skin the ViewNavigator to use this skin:

MyApp.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                            xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.ActionbarMoveHomeView" applicationDPI="160" >  
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        s|ViewNavigator {
            skinClass: ClassReference("VNSkin")
        }   
    </fx:Style>
</s:ViewNavigatorApplication>

Finally, in my view, I need to set the state and put it back when the view is activated and deactivated:

MyView.mxml

<?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="HomeView">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <s:viewActivate>
        navigator.skin.currentState = "moved";
    </s:viewActivate>

    <s:viewDeactivate>
        navigator.skin.currentState = "normal";
    </s:viewDeactivate>

    <s:Label text="test" click="navigator.pushView(SecondPage)" />
</s:View>

Note that this technique adds some overhead because your ViewNavigator skin is now MXML instead of pure ActionScript. You might consider creating a skin in pure ActionScript based off the ViewNavigatorSkin source code such that you can place it with your offset... but if you aren't noticing a huge performance hit from the MXML skin, I wouldn't worry about it.

EDIT I noticed after I wrote my answer that you only want it for one view. I have made a modification to add a state to the VNSkin class and then switch the states in the view code (viewActivate and viewDeactivate. For the record, this all feels like a hack. I'd consider some sort of notification mechanism so that you can communicate to the skin in order to change in a way other than this... but I have at least put you on a path to doing this with one technique. I'd love to see someone come here and suggest something better. Until then, you have something that works :P

Upvotes: 2

Related Questions