by Nathan D. on December 22nd, 2011

Recently, I began working on a new application which has a horizontal scrolling list of images (as clickable buttons). I looked into the new ScrollingList components in Flex 4.6 thinking, sweet! A simple parameter change to say "horizontal" instead of "vertical" and I'm good! Not so much... As anyone who's attempted something similar has come to realize, there is no such property in existance. However, after some simple hacking and a lot of head tilting, I've discovered a rather simple, yet complicated, workaround. Check it out below...
TestMobileProject.mxml (to simply render the view):
<?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.TestMobileProjectHomeView" applicationDPI="160">
<fx:Style source="main.css" />
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:ViewNavigatorApplication>
TestMobileProjectHomeView.mxml (as Referenced by the main app above):
<?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="Home">

<s:SpinnerListContainer width="100%" chromeColor="#FF0000" horizontalCenter="0" rotation="90" skinClass="skins.HorizontalSpinnerListSkin">
<s:SpinnerList height="100%" fontFamily="test" itemRenderer="TestItemRenderer"
labelField="data" selectedIndex="1" wrapElements="true">
<s:ArrayList>
<fx:Object data="image1.png"></fx:Object>
<fx:Object data="image2.png"></fx:Object>
<fx:Object data="image3.png"></fx:Object>
<fx:Object data="image4.png"></fx:Object>
<fx:Object data="image5.png"></fx:Object>
<fx:Object data="image6.png"></fx:Object>
</s:ArrayList>
</s:SpinnerList>
</s:SpinnerListContainer>
</s:View>
Now - the first thing of note in SpinnerListContainer: rotation="90". Thus, rendering our vertical scroller in a horizontal manner. I also created a skinClass to remove the default skin (which will also be displayed rotated 90 degrees as well.
<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>[HostComponent("spark.components.SpinnerListContainer")]</fx:Metadata>

<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>

<!--
Note: setting the minimum size to 0 here so that changes to the host component's
size will not be thwarted by this skin part's minimum size. This is a compromise,
more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
-->
<!--- @copy spark.components.SkinnableContainer#contentGroup -->
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="0" minHeight="0">
<s:layout>
<s:BasicLayout/>
</s:layout>
</s:Group>

</s:Skin>
Now- the more complicated part of this "hack"- the item renderers.
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="150" height="250">
<s:Image width="96" height="96" horizontalCenter="0" rotation="-90" smooth="true"
source="{data.data}" verticalCenter="0"/>
<s:Label right="4" fontFamily="Verdana" rotation="-90" text="{data.data}" verticalCenter="0"/>
</s:ItemRenderer>
It's pretty plain and simple actually. All my elements are rotated -90 degrees, effectively negating our earlier 90 degree rotation of the entire compontent. And what we end up with: a horizontally swipable scrolling container. You just have to swap the horizontal and vertical concepts in your item renderer (the complicated part). For instance, I put my label centered at the bottom of my item renderer. In order to put it in the correct position, I have to set horizontalCenter="0" and right="4". If I weren't rotating -90, I'd be adjusting different properties (verticalCenter and bottom respectively).
Enjoy!

by Nathan D. on November 16th, 2011

Believe me when I say, just about everything you want to style, move, adjust - whatever - since Flex 2 has been pretty straightforward and simple; except that pesky ComboBox drop down. I searched and scowered Google to no avail. Tonight, I finally conquered. All I wanted to do was trim the width down 20 pixels and center the dropdown on the button. However, there's just no simple way to pull that off. Here's a quick solution for anyone who runs into this issue. Create a custom component that extends the ComboBox control. One thing to note, I'm expecting a 16px scroll bar (that's default); hence the -16.


package com.nathanpdaniel.controls
{
import flash.events.MouseEvent;
import mx.events.DropdownEvent;
import mx.controls.ComboBox;

public class CustomComboBox extends ComboBox
{
private var isVisible:Boolean = false;
public function CustomComboBox()
{
super();

addEventListener(MouseEvent.MOUSE_DOWN, onClick);
addEventListener(DropdownEvent.CLOSE, onClose);

}

protected function onClick(event:MouseEvent):void
{
isVisible = !isVisible;
if (isVisible)
dropdown.x = (dropdown.x - dropdownWidth + width - 16);
}
protected function onClose(event:DropdownEvent):void
{
isVisible = false;
}
}
}

by Nathan D. on March 12th, 2011

I've spent many long nights getting a new application ready for the soon to be released Blackberry Playbook from RIM. From what I've seen so far, these things are going to be great! To be perfectly honest, it's the sole reason I have yet to purchase an iPad. As a developer, being able to develop for any device I own plays a major role in what technology I do purchase.
In school, I had a teacher (Coach A.) who made me write out goals every week. I hated it and never really gave it much effort. The only reason I even did it was to get the easy A (the class in it's entirety, not the easiest class I ever took). Now that I'm an adult, I get it. I have to set goals for myself on a regular basis to get anything accomplished. Usually, it's hand scribbled notes stuck to my desk, laptop, or bathroom mirror. Random notebooks stashed around the house which usually end up getting lost. Professionally, in my work place, we actually have quarterly and yearly goals we want to attain as well.
Now that I've become a software developer, I can actually do something about it. So, I introduce: MyGoals. Only about 2 steps beyond those weekly goal sheets I had to fill out in school. All it takes is a goal, when you want to accomplish the goal by and what steps will it take.
Here's the link: http://appworld.blackberry.com/webstore/content/32343
Below is the QR code to the application on Blackberry's AppWorld.

by Nathan D. on March 7th, 2011

There are plenty of encryption libraries out there for .NET and plenty for Flash/Flex. Getting them to communicate together on the other hand... well, just google .NET/Flex encryption and you'll soon realize, the two do not play very friendly.

We spent the better part of 5 days attempting every known encryption method out there via the AS3Crypto library (http://code.google.com/p/as3crypto/) (and 3 others freely available) on the Flex side and the same thing on the .NET side. Unfortunately, every test was a failure. 3 days into our attempts to decrypt a .NET encrypted string, we had some success as I was able to successfully pull out the first character of the encrypted string but nothing beyond that. We eventually settled on using an MD5 hash "system" to protect service calls. Not really wanting to settle on security, the .NET developer suggested one more attempt. Still unsuccessful until I altered one minor detail: encoding.

It turns out, on the .NET side, we were encoding the text in Unicode format before encrypting the string. Once it was passed over to Flex, I was never able to decode successfully because this. Once we updated the .NET to encode the string using UTF-8, I was able to successfully decode in Flex.

The one key from all the successful .NET to Flex encryption/decryption that I never saw: ensure your .NET encodes anything you want to encrypt in UTF-8 prior to encrypting.
.NET code:
public static string Encrypt(string plainText)
{
byte[] keyArray;
// path of file to encrypt
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(plainText);
string key = "RANDOMKEY";

keyArray = UTF8Encoding.UTF8.GetBytes(key);

System.Security.Cryptography.RijndaelManaged aes = new RijndaelManaged();
aes.Key = keyArray;
aes.Mode = CipherMode.ECB;
ICryptoTransform cTransform = aes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock
(toEncryptArray, 0, toEncryptArray.Length);
aes.Clear();
return Convert.ToBase64String(resultArray);
}

Flex code (using as3crypto):
private function decrypt(value:String, key:String):String
{
var keyByteArray:ByteArray = Hex.toArray(Hex.fromString(key));
var valueByteArray:ByteArray = Base64.decodeToByteArray(value));
var aes:ICipher = Crypto.getCipher("aes-ecb", keyByteArray);
aes.decrypt(valueByteArray);
return valueByteArray.toString();
}

by Nathan D. on December 8th, 2010

I am so excited to finally be able to speak about our latest project launch! Monday night (12-07-2010) we (Rockfish) officially launched our nations health statistics (http://statehealthstats.americashealthrankings.org) for United Health Foundation. The culmination of 8 weeks of in depth Flash development utilizing a whole slew of different technologies making for one impressive 3D experience for the user.
From the beginning, we knew given the size and scale of this project, Flex would be our base framework for building out the experience. We wanted a strong core to be able to compartmentalize every aspect via the architecture. Given the complexity of the application, we blended a miriad of architectural frameworks but used Cairngorm as the shell MVC. Beyond the standard view (of MVC), we broke development down even further to isolate the code controlling elements within the view via presenters. Doing so allowed several developers to work independently of each other on the same component. A beautiful display of teamwork and collaboration which we are definately honing within our work space.
We utilized Degrafa for all our skinning as we were tasked with building the entire application to target flash player 9. A major drawback given the advances in technology that come with flash 10. For all the 3D, we went with Away3D based on the ease of use compared to other 3D engines we've worked with in the past. By far, the experience with Away3D went significantly smoother than anything we've ever done to this point.
In all, we were able to stick almost precisely with the original designs with very little variance due to the collaboration supported in Adobe's Creative Suite 5. From the top down, the development of this experience went better than any of our expectations.


◀ Older Posts