Placing Flex-component in the middle of the screen - apache-flex

I have a very general question and have prepared a simple test case.
When using BasicLayout (i.e. absolute positioning) - what is the best approach to place a Flex component in the center of the application?
In the test case below I'm using x="{width/2}" but this gives me at least 2 problems:
How do I account for the component dimensions (the ProgressBar in the test case)?
Is the binding {width/2} a good idea to use? Wouldn't it send unnecessary DATA_CHANGE events in some cases?
And finally I wonder, how this all applies to full screen applications using StageScaleMode.SHOW_ALL - because currently my application is aligned to the top-left in the full screen mode and there is a white dead zone on the right of it. (Which is at least a change from pure Flash/AS3 behaviour, where the full screen content is displayed in the center of the screen and 2 dead zones on the left and right).
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="700" height="525"
backgroundColor="#CCFFCC"
initialize="systemManager.stage.scaleMode=StageScaleMode.SHOW_ALL">
<fx:Script>
<![CDATA[
private function fullScreen(event:MouseEvent):void {
stage.displayState =
stage.displayState == StageDisplayState.NORMAL ?
StageDisplayState.FULL_SCREEN :
StageDisplayState.NORMAL;
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="connected" />
</s:states>
<s:CheckBox right="10" bottom="10"
label="Full screen"
click="fullScreen(event)" />
<mx:ProgressBar indeterminate="true"
x="{width/2}" y="{height/2}"
label="Connecting..." labelPlacement="center"
includeIn="normal" />
</s:Application>

Way easier than that: just use horizontalCenter and verticalCenter properties of UIComponent. When used inside a BasicLayout the component will always be centered. Like this:
<mx:ProgressBar indeterminate="true"
horizontalCenter="0" verticalCenter="0"
label="Connecting..." labelPlacement="center" />
If you give these properties a value other than '0' the component will be offset from the middle by the amount of pixels you specify as a value. (e.g. horizontalCenter="50" will offset the component 50 pixels to the right of the center of the parent component)
That white space is probably due to your usage of systemManager.stage.scaleMode=StageScaleMode.SHOW_ALL. Just remove that line. Why are you doing that anyway?
edit
Just noticed you're using a fixed 'width' and 'height' on your Application: you'll have to make those '100%' if you want your app to really fill the screen. This is another possible cause for that white space.

To get your application centered (rather than left/right aligned) when using systemManager.stage.scaleMode=StageScaleMode.SHOW_ALL, set systemManager.stage.align to the empty string - i.e.:
// in your Application creationComplete handler
systemManager.stage.scaleMode = StageScaleMode.SHOW_ALL;
systemManager.stage.align = "";

I typically do 2 things,
I place objects inside VGroups/HGroups with alignment, I also use relative widths eg percentages.
Think like in the old days of using HTML tables. It works very well especially if your canvas is resized allot.
All of my canvases have to be resizeable as I like to only write my apps once, for pc, mobile etc, so I just make everything scalable by default.

Related

Fill entire content with a background image in Flex/spark

I created a 960x640px image which i want to use as background picture for any type of mobile device by scalling the image to the device s resolution.
How can i achieve this?
i tried:
<?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="MainView">
<s:Image width="100%" height="100%" fillMode="scale" scaleMode="stretch"
source="assets/background.jpg" />
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:View>
This looks good in the design view, it fill the whole screen but when i run the application everyting is really messy (the image is a lot smaller or a lot bigger than the mobile emulator screen)
Is there a better way to do this? Is it possbile to set a background-image directly on the view?
Thanks
set the fillMode="repeat"
this will repeat the image to fill the view

actionscript flex, how to send browser width to the swf itself

I'm working with flex, but actionscript ideas are just as good.
The flex <s:Application> tag has height="100%" width="100%" so the swf fits the browser as the browser gets resized.
My problem is that I have a <s:Label> that I need to position based on the real/current size of the browser.
<s:Application height="100%" width="100%">
.....
<s:Label text="hello" x="?" y=">" />
</s:Application>
I heard it's possible to use Application.application.width; but I get a compile error, that it doesn't know what that is.
Any ideas how to do this. I'm trying to get the current size of the swf in the browser, as the browser resizes.
As far as I can tell the following should work. Application.application simply is the same as this provided you are in the base application. The binding should allow the size to change after initialization.
<s:Application height="100%" width="100%">
.....
<s:Label text="hello" x="{width}" y="" />
</s:Application>
Edit : I just checked and it does work. To put your Label in the middle of the stage you simply have to put it like that
<s:Application height="100%" width="100%">
.....
<s:Label text="hello" x="{width/2}" y="{height/2}" />
</s:Application>
you could only know stage size when element is added inside stage, you could try a eventdelegate like this
app.addEventListener(Event.ADDED_TO_STAGE,init);
private function init(evt:Event):void{
trace(stage.stageWidth);
trace(stage.stageHeight);
}
Call a javascript function on browser resize. From there get the reference to the swf, and call the AS function to resize the label. Pass the browser width/height.
See example here
UPDATE: Correction: ExternalInterface goes AS to JS.
It's not completely clear what you are trying to do. x and y are positional elements, width and height are size elements. If you are positioning the label you should probably use top, left, right and bottom rather than x and y if you want it to size as the parent control sizes.
If you want the label centered you can use horizontalCenter and verticalCenter.
If you put it inside a layout control like a panel or a canvas you can just set its left and right to 0 and have the parent canvas size.
If your label is always in a different place depending on the size, you can override updateDisplayList to set the position. That holds whether you put it inside a layout control or not.

Flex : Cross resolution applications

What is the best way to create applications in Flex/AIR,
which look and feel the same irrespective of the screen
resolution?
When creating the layout in your flex application, you can achieve a consistent screen resolution independent look and feel from using relative scaling.
This is much akin to creating a liquid layout with HTML.
For example, to create a simple two column application— left navigation and content— you only need two containers, one predefined and one left to scale indefinitely.
As follows:
<mx:HBox width="225">
<mx:Button label="Menu 1"/>
<mx:Button label="Menu 2"/>
<mx:Button label="Menu 3"/>
</mx:HBox>
<mx:HBox width="100%">
Any content here will flow fluidly across the entire screen regardless of window size/screen resolution.
</mx:HBox>
Using the above basics you can create a application layout that forms to any screen.
However, sometimes you need to create a more elaborate layout scheme with many interchanging components resizing dynamically to fit the window.
For this you can do Absolute Positioning.
override the components updateDisplayList() function and create your own sizing/positioning rules.
This of course requires you to be within a Canvas container or have the main Application container set to absolute layout.
A simple example:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
{
//find out how big we are
var stageWidth:int = this.width;
//center the box in the middle of the page.
centeredBox.x = stageWidth - (centeredBox/2);
}
</mx:Script>
<mx:HBox id="centeredBox" width="500"/>
</mx:Application>
By overriding updateDisplayList() you can create endless ways to better dynamically position and size your components to better use the screen realestate.
You can create a application with height and width respective to the container so that way all components will aling themself properly at all screen resolutions.
We typically create a MainFrame.mxml which acts as our primary component and has layout relative scaling as mentioned by the others. Then we create the AIR app which just embeds that one MainFrame.mxml and another Flex app that embeds it as well. This way we can keep the entire app within MainFrame and not worry about if it is in Flex or Air. This being said you will need to make sure you do not use any AIR specific or Flex specific calls that do not translate to the other.

Limit width of custom list itemrenderer in Flex

I'm using a custom itemrenderer to display a list of photos and need to know how to control the width. At the moment it does this:
(source: tdwright.co.uk)
Which, as I'm sure you'll agree, is eye-bleedingly ugly.
The list is created like this:
<mx:Panel width="100%" height="100%" layout="absolute" title="Photos">
<mx:List x="0" y="0" width="100%" height="100%" id="photoList" dataProvider="{photos}" itemRenderer="thumbnails" rowHeight="100"/>
</mx:Panel>
And the itemrenderer component looks like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Image source="{data.src}" id="image" scaleContent="true" toolTip="{data.caption}" height="100%" horizontalAlign="center"/>
</mx:VBox>
I've tried placing width="100%" in a whole bunch of places, but without success. If anyone knows how I can control this I'd be very grateful.
If you set these properties inside the itemrenderer verticalScrollPolicy="off" horizontalScrollPolicy="off" the bars are disappeared
I don't know why they choose for the terrible "off" instead of False
A couple of observations here, based on a miasma of similar painful experiences. (Caveat: I have not built a test app to confirm everything here for this specific case)
Assuming that what you want is for the list to size its width based on the size of the itemRenderer elements it contains, those itemRenderer elements need to provide width information. Using a VBox in this fashion with scroll bars permitted means the VBox will attempt to "arbitrate" between the size of the content (Image) and the size of the parent. So yes, first thing to do is turn off the scrollbars on the VBox, assuming you can't just get rid of the VBox altogether. (I'm guessing you want the VBox so that you can put a title or something under the image as a next step)
The List as you have it specified is sized to 100% of its parent, the Panel, which is itself sized to 100% of its parent. Rather than size these elements "top down", consider letting their width be unspecified so that Flex will compute their required width bottom-up. Use maxWidth on the List or the Panel constrain their size if you need to for laying them out relative to their peers.
Another important thing to know about is the "minHeight=0" trick. Turns out, the sizing algorithm used by Flex behaves quite differently when minHeight or minWidth is set to something other than the default NaN. Setting it to 0 is extremely useful in many of these cases. Try minWidth=0 on the VBox and/or the List.
In addition to turning off the scrolling policy, set left and right to 0. That should anchor the width to the width of the parent.

Fluid layout of text in Flex3

In my Flex3 app I have some floating windows which contain variable amounts of text. The windows are meant to be user-resizable. Currently, while I can resize the windows OK, I can't get the text in a TextArea in the window to re-flow when the window is resized. I've come across blog postings that there's a size bug in TextArea that means that setting the text content does not re-size the TextArea properly, together with suggested workarounds. In my case, the content stays the same but the geometry of the container changes. What seems to be happening is that the TextArea adopts a fixed size when it is first rendered, and no amount of resizing the container changes that. Can anyone suggest a means of creating a fluid text area in Flex?
Ian
By binding the textArea's width to its container's with, you can manage to keep the margins and borders and don't have to deal with percentages.
Also, your textArea will be resized each time its parent changes in size.
i'm thinking of something like this:
<fx:Script>
<![CDATA[
import spark.layouts.supportClasses.LayoutBase;
protected function onButtonClicked(event:MouseEvent):void
{
currentState = (event.target.selected ? 'largeState' : 'smallState');
}
]]>
</fx:Script>
<s:TitleWindow id="window" width="300" height="200">
<s:TextArea width="{window.width - 10}" height="{window.height - 60}"
text="{IMyConsts.LOREMIPSUM}" borderVisible="false" />
<s:ToggleButton id="btnEffect" bottom="5" click="onButtonClicked(event)"
label="{btnEffect.selected ? 'Go smaller' : 'Go larger'}" />
</s:TitleWindow>
<s:states>
<s:State name="smallState" />
<s:State name="largeState" />
</s:states>
<s:transitions>
<s:Transition fromState="smallState" toState="*">
<s:Resize target="{window}" widthTo="400" heightTo="300" />
</s:Transition>
<s:Transition fromState="largeState" toState="*">
<s:Resize target="{window}" widthTo="300" heightTo="250" />
</s:Transition>
</s:transitions>
I found a great example of fluid windows please do visit it. They provide source code also so may be you would get better idea.
http://examples.adobe.com/flex3/devnet/dashboard/main.html
You could try Text Layout Framework from Adobe:
http://labs.adobe.com/technologies/textlayout/
I can take a whack at this... but don't laugh..
I am not sure if you need to use a particular container but in any event, set the width and height to 100% and use Grid > GridRow and GridItem to size and resize Text Control you can specify the width of the table or just use it just like an HTML table in Flex to manipulate the size of controls and containers....
hope that helps...

Resources