skinning view in flex mobile to add background: is that a bug? - apache-flex

I added a background to my views in flex mobile.
I just realized that if I do not include that line:
<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0"/>
only my image is shown and I cannot show anything else.
The very strange thing is that I used :
new-mxml skin
and host component: spark.components.View
and the wizzard did not add this crucial line (I have found that on samples):
<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0"/>
1) Is that a bug ? or is there another simpler way do that ?
2) to avoid others bugs like this one, is there some good practises to skin other components ? (using catalyst ? using fireworks ?)
Regards

Is that a bug ? or is there another simpler way do that ?
No, that's not a bug. The skin for a View class has "skin part" named contentGroup, and this is the object that the View component uses to display its child components. Without this skin part, your view has no container to hold the child components.
Every component that has a skin defines a set of "skin parts". Some skin parts are required, others are not.
Strangely enough, the contentGroup skin part is not required, though it's pretty useless to exclude it.
To avoid others bugs like this one, is there some good practises to skin other components ?
The best practice is to look at the documentation to see what skin parts a component declares. For example, here is a link to the "skin parts" section of the docs for the View component. On the top right of every page in the docs, there is a "skin parts" link to jump to this section of the page.
When you use the wizard to create an MXML Skin, you have an option to copy the code from one of the existing skins that Flex defines. If you do this, you will get some code that includes all of the skin parts and a bunch of Adobe styling code.
If you do not copy the original skin, you get an empty MXML skin. However, the wizard will create a comment in the the code telling you what the skin parts are, and if they're required or not. Here's the comment you get when creating an empty View skin:
<!-- SkinParts
name=contentGroup, type=spark.components.Group, required=false
-->
You can use other tools like Catalyst, but they're not necessary (I believe Catalyst has been discontinued anyway). Sometimes I start by creating the skin w/Adobe's default code and stripping away what I don't want. Other times there's so much "clutter", I just use a blank skin.

Related

Using IntelliJ IDEA 12 for Flex Development

I have been using Flex / Flash Builder for a number of years. The latest release of Flash Builder (4.7) seems to come with quite a few problems, the biggest of those being:
Does not detect component IDs in MXML. For example, you cannot Find Usages of the ID of a component. Keeping the cursor on the ID of a component does not even mark occurrences of the ID. Instead, it marks occurrences of the actual id words in the MXML.
Extremely slow.
I am seriously evaluating moving over to IntelliJ IDEA 12, especially after reading many experienced Flex devs raving about it and recommending it.
I tried it. It took me a while to get to terms with the new terminologies of the IDE (made easy by this doc and very helpful support personnel at JetBrains).
I was able to setup my (large) projects in IDEA with Adobe Flex 4.6 SDK and got it to compile fine. But I noticed many "errors" highlighted in my AS files which are all actually false alarms.
The ActionScript editor doesn't seem to recognise the objects defined in MXML. Apparently, this is a known bug in IDEA (tracked here). And this bug has existed for more than 2 years!
Quoting the JetBrains support personnel:
I must admit that highlighting of ActionScript files which do not contain classes, but instead included in mxml as <fx:Script source="some_file.as"/> is probably the only weak part of IntelliJ IDEA code highlighting. False error highlighting will go away if you embed AS code inside CDATA of <fx:Script/> instead of referencing as external *.as file. Though I understand that this is not always desired.
I'm afraid the fix won't go into 12 release because the release is very soon and the fix is too risky. Priority of the issue depends on votes and user feedback. So far we have only 2 votes (http://youtrack.jetbrains.com/issue/IDEA-52598) and as the fix is pretty complex we still haven't implemented it thinking that this is a rare use case. I hope to fix it in one of 12.x update releases.
My project is a huge one, with huge MXML files and even more huge AS code for each MXML. So, for organisation purposes, I need to logically split them into smaller files. So, merging the AS code with the MXML is not practical. The false error highlighting just drastically reduces the readability of the code. Also, it does not allow Control / Command-clicking component IDs in AS code to quickly navigate to the definition of the component in MXML (which, incidentally, is now broken in FB 4.7 as well, but worked well in FB 4.6).
This bug in IDEA is unfortunately a deal-breaker for me. But I am wondering how other Flex devs are able to overcome / work around this seemingly critical bug.
It seems unbelievable to me that just 2 people have been affected by this bug, especially with so many Flex devs recommending IDEA. Maybe I am doing something wrong?
All you Flex developers, I would appreciate your thoughts.
UPDATE
This is in response to RIAStar's excellent and detailed answer. But it doesn't quite help me completely. Let me explain why and how I use <fx:Script source>. I am using Flex 4.x, with almost only Spark components.
Suppose a brand new Flex project. The main application is an MXML file.
In this MXML file, suppose I have a signup form.
On editing the form (in each field), suppose I have to run validations and enable the Submit button only if the form is completely valid. This would mean I need to assign change event handlers to the form items. The event handlers is AS code.
Suppose there is a username field which needs an on-type uniqueness check, by calling the server asynchronously. The server communication code is also AS code.
And then of course, there is the Submit button handler, which is also AS code.
I usually put all the AS code in separate .as files and include it in the MXML using <fx:Script source>. This AS code is usually quite heavy, with a lot of functional and behavioural logic. Many times, based on user action, even the components in the MXML and layout of the elements is modified through this AS code.
If I understand you guys right, none of this event handler code should be in these MXML script files. So, where should it be? How do you guys do it? I am not sure how the Spark Skinning architecture has anything to do with this.
Since I can't think of a gentle way of putting this, I'll just be blunt: I'm afraid the reason only two people think this is a critical bug, is that most seasoned Flex developers will agree that using <fx:Script source="some_file.as"/> is bad practice.
You effectively create two files that represent one class. From a readablity POV, which you seem concerned about, that's not a good move. One of these files (the .as file) is just a bunch of functions that cannot exist in their own right: they are tightly coupled to another file/class, but just looking at the .as file there is no way of knowing which class it is coupled to. Of course you can use some kind of naming convention to work around this, but in the end ActionScript/Flex is supposed te be used as a statically typed language, not a scripting language relying on mixins and naming conventions (don't get me wrong: I'm not saying scripting languages are bad practice; it's just not how ActionScript was conceived).
So what are your alternatives?
I suppose the main reason behind this construct is that you wish to separate MXML from ActionScript code, or in more abstract terms: separate the view from the logic. Fortunately this can be achieved in a few other, cleaner ways. Which solutions are available to you depends whether we're talking Flex 3 (or earlier) or Flex 4.
I realise that you may not have time to refactor your code to one of the proposed solutions, but I didn't want to leave you with just a "that's not good practice" answer.
Flex 3 (mx)
Code behind: A lot of developers used the so-called "code behind" pattern to separate their logic from their view. You can find plenty of information on the topic by Googling "flex code behind". I don't need to repeat all that in here. I'm not much of a fan of the concept because it relies heavily on inheritance and the two resulting classes are still pretty tightly coupled, but at least we're talking two classes. If you design your architecture well, you may even be able to reuse some of your base classes.
Compose model en controller: I used to create a separate "presentation model" class and a "controller" class for each MXML view and then use it something like this:
<!--MyView.mxml-->
<mx:VBox>
<m:MyModel id="model"/>
<c:MyController model="{model}" view="{this}"/>
...
</mx:VBox>
MVC purists won't like this, but it worked pretty well for me in thencontext of Flex applications.
Later when Direct Injection supporting frameworks (like Parsley) made their appearance, I could use injection to wire all those classes instead of hard-wiring them like in this example.
MVC frameworks: My knowledge of this topic is sparse (because in my opinion Flex is a very decent MVC framework that requires no third-party additions, but that's another disussion), but in short: they can help you separate logic from view in a clean way.
Flex 4 (Spark)
With Flex 4, the Spark skinning architecture was introduced, which allows for very nicely separated view and logic. You create a so-called 'host component' class in plain ActionScript, which contains all of the behavioural code, and a 'skin' class in MXML which defines the visual representation of the component. This makes designing reusable components very easy.
As per your request, here's a simplified example of how you might use Spark skinning to create your signup form.
Let's start with the skin class since it's easy to understand. It's just a form with some input fields. The HostComponent metadata tells the skin it's supposed to work together with the SignUp host component.
<!--SignUpSkin.mxml: the visual representation-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Metadata>
[HostComponent("net.riastar.view.SignUp")]
</fx:Metadata>
<s:Form>
<s:FormHeading label="Sign up"/>
<s:FormItem label="User name">
<s:TextInput id="userInput"/>
</s:FormItem>
<s:FormItem label="Password">
<s:TextInput id="passwordInput" displayAsPassword="true"/>
</s:FormItem>
<s:Button id="submitButton" label="Submit"
enabled="{hostComponent.canSave}"/>
</s:Form>
</s:Skin>
And now the host component in pure ActionScript. It has to extend SkinnableComponent to be able to use our skin (there's also SkinnableContainerwhich I've just recently explained in this question: Flex mxml custom component - how to add uicomponents?, but we won't be needing that here).
public class SignUp extends SkinnableComponent {
[SkinPart(required="true")]
public var userInput:SkinnableTextBase;
[SkinPart(required="true")]
public var passwordInput:SkinnableTextBase;
[SkinPart(required="true")]
public var submitButton:IEventDispatcher;
[Bindable]
public var canSave:Boolean;
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);
switch (instance) {
case userInput:
userInput.addEventListener(TextOperationEvent.CHANGE,
handleUserInputChange);
break;
case passwordInput:
passwordInput.addEventListener(TextOperationEvent.CHANGE,
handlePasswordInputChange);
break;
case submitButton:
submitButton.addEventListener(MouseEvent.CLICK,
handleSubmitButtonClick);
}
}
private function handleUserInputChange(event:TextOperationEvent):void {
validateUsername(userInput.text);
}
...
}
What's important here?
The variables marked as SkinPart will automatically be assigned the components with the same id that exist in the Skin you just created. For instance <s:TextInput id="userInput"/> will be injected into public var userInput:SkinnableTextBase;. Note that the type is different: SkinnableTextBase is the base class of TextInput; this allows us to create another skin with e.g. a TextArea instead of a TextInput and it'll work without touching the host component.
partAdded() is called whenever a SkinPart is added to the display list, so that's where we hook up our event listeners. In this example we're validating the username whenever its value changes.
When the validation is done, you can simply set the canSave property to true or false. The binding in the skin on this property will automatically update the Button's enabled property.
And to use both of these classes together:
<v:SignUp skinClass="net.riastar.skin.SignUpSkin"/>
I actually have become quite fond of using RobotLegs.
In my MXML views I try to keep all logic outside of the MXML and simply dispatch events out to the mediator. From there I can put code in the mediator to the heavier AS needed.

Workaround for AdvancedDataGrid flicker in Flex Hero 4.5.0.19786

Since I updated to the latest build of Flex Hero (4.5.0.19786) AdvancedDataGrids flicker in design view with Flash Builder Burrito preview. Has anyone run into this and if so is there a work-around besides dropping back a version?
Update 02 19:29
This did not occur in previous Hero builds, e.g 18623. I am using the default Spark theme, nothing else particularly special.
Update 01 19:15
I tracked down the problem to an instance of a custom (default custom, i.e the result of doing new->component based on AdvancedDataGrid) on the same form.
The component declaration:
<?xml version="1.0" encoding="utf-8"?>
<mx:AdvancedDataGrid
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</mx:AdvancedDataGrid>
The custom component instantiation. Note "fo" is a namespace representing the path to the package for which the custom component resides.
<fo:adgTest width="300" height="200">
<fo:columns>
<mx:AdvancedDataGridColumn headerText="blah1" />
<mx:AdvancedDataGridColumn headerText="blah2" />
</fo:columns>
</fo:adgTest>
It turns out that this custom version of AdvancedDataGrid causes the design view to break down. Very odd.
Update 03 2011-02-11 13:36
A custom AdvancedDataGrid does not cause design-view breakdown unless I add columns to it.
Update 04 2011-02-11 15:13
Filed as a bug: https://bugs.adobe.com/jira/browse/SDK-29507
I think, this is not the problem of sdk. Its a problem of the designer (Flex Burrito). I have exactly the same envoirment, and my version of burrito is 287807.
My AdvancedDataGrit does NOT flicker!
Do you have some styles applied or something else?
After following your steps described in your question, i also have a flickering custom AdvancedDatagrid on my stage. When i click to another component (tab) and go back to the implemented adg, the flickering stops.
When i close the Component with the flicker adg in it and open it again, the adg flicker again.
With the preversion of the sdk the adg doesn't flicker. I notice also, that the graphic is different.
In the preversion, i can see some folderIcons wirh teh expanded or closed arrows.
After switching to 19786 the foldericons disapear and the flickering starts.
There is something wrong and i would start a thread in adobe bug base.
In my opinion, you did nothing wrong. There is no better way and it is equal if i drag the custom ADG or code it in codeview. The result is always a flicker adg in designview.
Sorry for the misunderstands and my bad english
BR Frank

What is the purpose of 'fb:purpose' in a Flex <fx:Script>?

I've now seen it a few times here and there and it's got me curious.
<fx:Script fb:purpose="styling">
//script stuff
</fx:Script>
So far, I have seen no difference with it there and without it. Nor do I get any compiler erros. How does a script with fb:purpse differ from a script without? What are the consequences for not including a fb:purpose and what are the benefits for including a fb:purpose?
From the Flex 4 documentation:
Most Spark skins have a special block at the top of the skin class. This block typically defines style properties that the skin class respects, including the exclusions that the skin uses. The tag includes a special attribute, fb:purpose="styling":
<fx:Script fb:purpose="styling">
This attribute is used by Flash Builder. When you create a copy of a skin class in Flash Builder, you can opt to make the skin styleable. If you choose to make it styleable, Flash Builder includes this section of the skin class. If you choose not to make the skin styleable, Flash Builder excludes this section.
It's part of the flashbuilder namespace, and won't have any effect on compilation.
There's no documentation for it that's publicly available at the moment, but it's usually generated by FlashBuilder itself, or is included in the Flex framework code from Adobe.
It's used to show the purpose (in a tool readable manner) of a script block, in this case, styling.
If you create a new MXML Skin using Flash Builder (File > New > MXML Skin) you can deselect the "Remove ActionScript styling code" checkbox which signifies that Flash Builder should remove the script block that defines fb:purpose="styling".
As Yaba said, it allows you to check or uncheck "Remove ActionScript Styling" when building a new MXML skin by copying another Skin class.

Is it possible to create skinnable components in MXML using the Spark component architecture?

There are lots of examples of how to create skinnable components in AS3 using the new Spark component architecture, however I've yet to find any such examples using MXML.
What I'm mainly referring to is defining the skin parts and skin states. It seems as though the SkinPart metadata is supposed to be associated with properties and as such can't be used in MXML, is this correct?
As far as I can tell, this isn't possible, because - as you rightly pointed out, there's no way to assign property-level metadata in MXML.
But declaring skin contracts in MXML seems like it would go against the spirit of the Skinning architecture, which is to separate the view of the component from it's implementation logic.
And, given that in MXML everything declared has a value, it inherently couples the component to a skin.
Ie:
<!-- labelDisplay has a value -->
<s:Label id="labelDisplay" />
vs
[SkinPart]
public var labelDisplay:Label; // labelDisplay == null;
Likewise, most of the component logic itself would end up in a <fx:Script /> block, which would probably be better suited in a seperate class.

does actionscript addChild require a display object first

Solution:
if you have the same problem, addElement() instead of addChild() is what did it
I'm trying to move away from mxml to actionsctipt. I have a <s:Rect> that I've created and set its properties, but having trouble adding it.
var aRect:Rect = new Rect();
//set properties like aRect.x, aRect.y, aRect.width, aRect.height
//tried adding it various ways
addChild(aRect);
Application.addChild(aRect);
Application.application.addChild(aRect);
stage.addChild(aRect);
But I keep getting the error
1067: Implicit coercion of a value of type spark.primitives:Rect to an unrelated type flash.display:DisplayObject
Originally in the mxml, it was right inside <s:Application> not nested inside anything
<s:Application>
<s:Rect id="aRect" x="10" y="10" width="15%" height="15%">
//then fill code here, removed for readability
</s:Rect>
</s:Application>
What's the deal, I thought actionscript would be nicer than mxml.
tried changing addChild(aRect); to addElement(aRect); and that worked beautifully.
It's because Flex 4 significantly changed the way the display hierarchy works in MXML-based applications. This is a bit confusing since addChild() no longer works as simply as you'd want it to - you have to add elements to a dataprovider, and then the logic of displaying those elements (which ones to add where, how to skin them, etc) is handled elsewhere. It's kind of a useful change, though, because it forces you separate your concerns in a very concrete way. Once you have your elements all added to your dataProvider you can swap out Layout objects at will (even at runtime) to change the way your application looks.
EDIT: Technically it's not the displayList itself that they've changed. It's the fact that the basic unit used by Flex is now the "Group" - even s:Application extends group. You add your content to a a Group (or to the top level Application) and then you assign the group a layout to tell it how to display the items you've added.
Yes, you need a DisplayObject. I'm not familiar with spark.primitives.Rect, but perhaps you could just create a new Sprite and call methods on its Graphics object to draw the rectangle?
According to the live docs, the addChild method of the Application class does require it to be a displayObject.
Annoyingly we will often struggle to add flash assets ( swf swc ) (display objects) using addElement.
I'm working on a way to do this right now :( more hoops and jumping
Also my swc is not viewable in the package explorer (why not ?)

Resources