I’ve been working on a mobile application in the recently released Flash Builder 4.5, which has support for exporting native apps for iOS and Android. While the engineering is largely sound and well done (with the exception of some big-name missing components from the “mobile-optimized” list, such as ComboBox), there are definitely a few glitches that I’ve encountered thus far in my experience with it. One such glitch is in the TextInput component.
In the mobile app that I’ve been working on, the design calls for the text input label to be placed “inside” of the text input field, on the left side. As such, I needed to add left padding to the TextInput component, so the text field wouldn’t overlap the label, which was sitting behind the TextInput control. So I set up my code to include the appropriate padding, and tested the result. When viewing the application, it looked just like it should, with the label positioned “inside” the TextInput component.
However, when I started typing a value into the fields, that’s when I saw the glitch:
The problem was this: When typing in your text into the field, and the text goes longer than the width of the visible width of the text field inside of the component, you completely lose the cursor and can’t see the text you’re entering. That is, until your text width is as long as or greater than the width of the TextInput component. Then, your text suddenly shifts, with the text field taking up 100% of the width of the TextInput component. So naturally, I let out a huge sigh and asked, “What happened to my left padding? Did I do something wrong?”
The answer to my question is this: The padding never got incorporated into the component correctly. And no, I didn’t do anything wrong. Adobe did.
In my wrestling with how to fix this issue, I copied over the default TextInputSkin file (spark.skins.mobile.TextInputSkin) and put it into my project files. Then I opened it up and started investigating. Here’s what I found:
In the “layoutContents” method, I found a very big issue with the logic. And while it may seem like a small, innocent issue, it looms large when trying to add padding of any sort to the component. The issue is caused by 3 errors in the code of this function.
textDisplay.leftMargin = paddingLeft;
textDisplay.rightMargin = paddingRight;
These two lines are worthless. Why? It doesn’t solve any problems. It creates the skip in the text inputting described above, specifically when paired with the other two errors below. So, I commented these two lines out.
setElementSize(textDisplay, unscaledWidth, adjustedTextHeight);
This error is just plain and simple wrong. There’s a variable for “unscaledWidth”, which is the width of the ENTIRE component, NOT the width of the textDisplay (i.e. text field) after having padding taken into consideration. There’s actually a variable called “unscaledTextWidth” in the code, which is the value that SHOULD be used in this instance of “setElementSize”, because the textDisplay should have a width that has the left and right padding taken into consideration. So, I changed this line to be:
setElementSize(textDisplay, unscaledTextWidth, adjustedTextHeight);
setElementPosition(textDisplay, 0, textY);
This error, like the last, is also just plain wrong. The 2nd argument for the “setElementPosition” method is the X value, which you’ll notice is HARD-CODED to “0”. This means that no matter what your left padding value is, the textDisplay will ALWAYS be set to the left side of the component. The x value should be based on the value of the left padding. So, I changed this line to be:
setElementPosition(textDisplay, paddingLeft, textY);
With the 3 errors above fixed, my TextInput component was finally working as intended, with the correct padding values, no intermittent skipping, and no random resizing of the text field inside of the component. Rather, like any other good text input field out there, it only displays the text width it should, while hiding the rest.
So if you find yourself questioning why something isn’t working as intended, take a few minutes (or hours, in some unfortunate instances) and look into the class/component/code you’re working with. Not only will you get a better understanding of how everything is set up, but you might just find another spot where the software engineers overlooked something and made an error.
Until next time, happy coding!
Even though I am not a fan of how Adobe laid out this TextInputSkin, I must admit that I can see how/why it was done the way it was. There aren’t many times where a mobile application would call for a situation like the one I had. Chances are, Adobe’s quality assurance and testing didn’t think to include such a circumstance. After all, most mobile application components like text input boxes are set up to take up 100% of the screen (or close to it) to optimize hit area and visual space. So, giving them the benefit of the doubt, I can’t say I’m mad at Adobe for how they put things together. But I stick to my statement that if something isn’t working as intended, take some time to look into the code behind the scenes. You just might find something in need of fixing.