What to use as base for a custom MXML component? - apache-flex

I'm using several custom MXML components in my Flex 4.5 application.
They all use absolute coordinates to place Image, Label, Line, etc. components and are currently based on a spark.components.BorderContainer:
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer
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="160" height="140" borderWeight="0"
creationComplete="init(event)">
<s:layout>
<s:BasicLayout />
</s:layout>
<s:Image id="_avatar" x="0" y="0" width="160" height="120" />
<s:Label id="_username" x="1" y="122" width="80" />
<s:Label id="_bid" x="80" y="122" width="40" textAlign="center" />
<s:Label id="_trix" x="120" y="122" width="36" textAlign="right" />
.... and so on: Images, Labels, Paths, Lines, Rects ....
</s:BorderContainer>
Then I've realized, that I probably don't have to use BorderContainer, because I don't draw/need any borders around my custom components.
But I don't know, what to take instead of it.
I've tried taking <mx:UIComponent> (and removing <s:Layout> tag above), but then I get the error:
'Image' declaration must be contained within the <Declarations> tag since it does not implement 'mx.core.IUIComponent'.
'Label' declaration must be contained within the <Declarations> tag since it does not implement 'mx.core.IUIComponent'.
Any suggestions please? Is there some simplest possible spark "container"? And do I need a "container" at all if I use (and want to use) absolute coordinates?

I recommend you to use s:Group. And you can omit layout declaration as far as BasicLayout is default layout.
UIComponent isn't container so it hasn't default placeholder for children to add them with MXML.

Related

Adobe Flex List Itemrenderer: Cannot Scroll List

I have have successfully set up a list that pulls users from a database and displays them in a list. I'm currently customising the list with an itemrenderer and it's going well. I can pull a user's profile picture, then to the right of it I'll display their name and underneath is their age. The problem is that I can only fit 4 results into the list and I can see the top of the 5th, but there's no scroll bar. I would show a print screen but I populated my database with real info about my friends and their facebook details, so i'd rather not.
In my main mxml programme I have the following code:
<s:List id="resultList" includeIn="loggedin" x="120" y="246"
width="100%" itemRenderer="userList">
<s:layout>
<s:VerticalLayout useVirtualLayout="true" requestedMinRowCount="1"/>
</s:layout>
<s:AsyncListView list="{getUserResult.lastResult}"/>
</s:List>
In userList.mxml I have the following code:
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<s:Image id="fbImg" source="http://graph.facebook.com/{data.facebookid}/picture?type=normal" x="0" y="0"/>
<s:Label id="usernameLbl" x="120" y="0" fontFamily="Calibri" fontSize="25" fontWeight="bold" text="{data.firstname} {data.lastname}"/>
<s:Label id="ageLbl" text="{data.dob}" x="120" y="40" />
</s:ItemRenderer>
Does anybody know why I cannot scroll all of my results? I'm sure it's something very simple that I do not know about.
EDIT: I'm so sorry for the horrible formatting. I can't seem to get my code to display nicely.
Assign a height to your list and all will be right in the world. If you don't, it assumes it can extend past the bottom of your page to show all the data even if you cant see it.
<s:List id="resultList" includeIn="loggedin" x="120" y="246"
width="100%" height="100%" itemRenderer="userList">
<s:layout>
<s:VerticalLayout useVirtualLayout="true" requestedMinRowCount="1"/>
</s:layout>
<s:AsyncListView list="{getUserResult.lastResult}"/>
P.S. Great question with lots of detail and perfect amount of code.
I had a problem with List seeing the percent height (height="100%"). So, I had to set it using something like height="{myContainer.height}" and it worked.

ItemRenderer Doesn't Resize with DataGrid Column

I have an item renderer tied to an mx:DataGrid column. The renderer used to be inline with the column, but I've moved it out to its own file so I can reuse it across multiple tables.
The problem is that now the renderer doesn't resize (grow/shrink) when the column is resized. So if the user makes the column very small, the contents displayed by the renderer just eat up space and show up over top other columns Any ideas how to make this work?
Code for Item Renderer:
<?xml version="1.0" encoding="utf-8"?>
<s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true">
<mx:HBox verticalScrollPolicy="auto" horizontalScrollPolicy="off" width="100%">
<mx:Spacer top="0" bottom="0" width="4" />
<mx:Image id="typeIcon" buttonMode="false" source="{data.type}" />
</mx:HBox>
</s:MXDataGridItemRenderer>
Code for column using that renderer:
<mx:DataGridColumn headerText="Type" dataField="type" itemRenderer="com.myCompany.myProject.TypeRenderer" />
Edit
Adding width=100% to the MXDataGridItemRender didn't work.
I posted my question on Adobe's flex forum -- the solution was to remove the outer s:MXDataGridItemRenderer and to just let the mx:HBox be the root control (no other changes were necessary.)
Strange that he Flex Builder app doesn't give you the option of defining the outermost control, it just plops an s:MXDataGridItemRenderer on top...

Setting background image in Flex 4.5

I have written a custom skin in Flex 4.5, which shows a custom image. I want this to my background image, so how can I set this skin to the application container?
Thanks
You skin the application like any other component, the skinClass attribute of course! :)
How?
Here is my app.mxml :
<?xml version="1.0"?>
<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"
skinClass="MyAppSkin">
</s:Application>
Now, here I make a simple skin with a background image stretched to fit!
Full source of my MyAppSkin.mxml file here (too big to post here): http://pastebin.com/Hwu9tc1Y
Here is the important part (only part really customized - rest is standard) :
<s:Group id="backgroundRect">
<s:BitmapImage source="#Embed('beach.jpg')" left="0" right="0" top="0" bottom="0" scaleMode="stretch"/>
</s:Group>
What happens when you apply a skin is that it searches for certain elements by id (backgroundRect being the one we're interested in) and applying them. To customize, simply change the parts of the skin you want. I replaced the standard background solid color fill with this group with an image.
Piece of cake sir!
Make sense?
How about this:
<s:BitmapImage source="#Embed('paper1.jpg')"
left="0" right="0"
width="100%" height="100%"
/>
Set background image and add components
<mx:VBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
<s:List>
<s:ArrayCollection>
<fx:String>One</fx:String>
<fx:String>Two</fx:String>
<fx:String>Three</fx:String>
<fx:String>Four</fx:String>
<fx:String>Five</fx:String>
</s:ArrayCollection>
</s:List>
</mx:VBox>
</s:Group>

Height problem with automatic word wrapping in MXTreeItemRenderer in a flex tree

With the default TreeItemrenderer it is possible to enable automatic word wrapping depending on the tree width by setting wordWrap=true and variableRowHeight="true" in the tree control.
I would like to enable this behavior in a MXTreeItemRenderer (a wrapper for using spark components as mx itemrenderer).
I used the MXTreeItemRenderer created by Flexbuilder and added a width of 100% to the label component (see code below).
Word wrapping is working now but in many cases the calculation of the item renderer height is wrong when there are line breaks. It seems to work with a fixed width.
Any idea how to get this right?
<s:MXTreeItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:HGroup left="0" right="0" top="0" bottom="0" verticalAlign="middle">
<s:Rect id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" alpha="0">
<s:fill>
<s:SolidColor color="0xFFFFFF" />
</s:fill>
</s:Rect>
<s:Group id="disclosureGroup">
<s:BitmapImage source="{treeListData.disclosureIcon}" visible="{treeListData.hasChildren}" />
</s:Group>
<s:BitmapImage source="{treeListData.icon}" />
<s:Label id="labelField" text="{treeListData.label}" paddingTop="2" width="100%"/>
</s:HGroup>
</s:MXTreeItemRenderer>
Well you should probably file a bug first off ;)
If it's not reporting the height correctly, override the measure(..) method and work out the height yourself, you'll probably have to use line metrics (If they are still around in Spark) to work it out.
I found out that the height is calculated correctly when it is done twice.
So as a workaround for now I listen to changes of the data and the size and call the invalidateList() Method of the tree on a change.
In this blog site, someone pointed me to this site
really nice one, it helped me. I think it works for varying row height. Nodes with wrapping text should work.
Enjoy!

Making image span across several components in Flex

Recently I've found a nice on-line diagramming tool - LovelyCharts. I like the way UI is designed - you can view screenshot here. I wonder how to make an image that span across multiple components, like the LovelyCharts logo in the upper right corner of the screenshot. Could anybody kick me in the right direction?
You need to create an image with a transparent background. The JPEG format does not support transparent backgrounds so you need to use GIF or another format. Then embed the image as in the following code.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical">
<mx:Canvas width="476"
height="264">
<mx:Label x="103"
y="110"
text="Some text"
width="155"/>
<mx:Image x="115"
y="110"
width="100"
height="100"
source="#Embed('assets/transparent_back.gif')"/>
</mx:Canvas>
You can position the image where you want on the canvas, overlapping other components if you like. Here is an example of an image with a transparent background, http://commons.wikimedia.org/wiki/File:Gluecksklee_%28transparent_background%29.gif
This should definitely work for you. The layout of the application is absolute and there are two examples of images - one declared inside the canvas tags and the other outside
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Canvas width="476"
height="264"
x="50"
y="0"
borderStyle="solid"
borderThickness="5"
borderColor="black">
<mx:Label x="103"
y="110"
text="Some text"
width="155"/>
<mx:Image x="115"
y="110"
width="100"
height="100"
source="#Embed('assets/transparent_back.gif')"/>
</mx:Canvas>
<mx:Image x="30"
y="110"
width="100"
height="100"
source="#Embed('assets/transparent_back.gif')"/>
</mx:Application>

Resources