Posts tagged "flex"

Using Bitmaps in Flex Mobile Projects

Bitmap image assets typically only render optimally at the resolution for which they are designed. This limitation can present challenges when you design applications for multiple resolutions. The solution is to create multiple bitmaps, each at a different resolution, and load the appropriate one depending on the value of the application’s runtimeDPI property.

The Spark BitmapImage and Image components have a source property of type Object. With this property, you can pass a class that defines which assets to use. In this case, you pass the MultiDPIBitmapSource class to map different sources, depending on the value of the runtimeDPI property.

The following example loads a different image, depending on the DPI:

<s:Image>
  <s:source>
    <s:MultiDPIBitmapSource
      source160dpi="@Embed('assets/160.png')"
      source240dpi="@Embed('assets/240.png')"
      source320dpi="@Embed('assets/320.png')"/>
  </s:source>
</s:Image>
<s:Label text="applicationDPI = {FlexGlobals.topLevelApplication.applicationDPI}"/>


Normally, you would take the same content and scale (and/or design) it for each DPI. For clarity, I’ve created 3 different images for each DPIClassification. The source images are shown together here at their full resolution:


When run on a device, the MultiDPIBitmapSource class selects the appropriate asset based on the runtimeDPI, not the applicationDPI. The bitmap itself is present unscaled, even though the application itself may be using application scaling. The 2 photos below show nearly identical applications. The only difference is that the second application labeled “Bitmap Demo Scaling” is using applicationDPI=”160″. You’ll see that in both cases, the correct bitmap is used. And because of the screen DPI of each device, the physical size of each bitmap is approximately the same.

The main point here is that regardless of which scaling strategy you choose, you should always use MultiDPIBitmapSource when displaying bitmaps in mobile Flex projects.

No Scaling. iPod Touch 4th gen, HTC EVO and BlackBerry PlayBook

 

Scaling with applicationDPI="160". iPod Touch 4th gen, HTC EVO and BlackBerry PlayBook

 

Share on Facebook

Developer Week Sessions

I’m giving 2 mobile related sessions at this year’s Adobe Developer Week. Here are my session titles, times and descriptions:

Multi-density and multi-platform authoring for smart phones and tablets with Flex 4.5 SDK – Tuesday, June 21, 2011 1:00 P.M. Pacific
Learn what multi-density on devices means, why it is important and how to leverage the support available in Flex 4.5 to address the challenges.

Creating performant skins and item renderers for mobile applications – Friday, June 24, 2011 11:00 A.M. Pacific
Dive deep into skinning mobile components. We will demo creating a skin that looks like a native iOS component.

I’ve covered skinning and how to handle DPI a little bit here on my blog. My first session will provide an overview of the topic and I’ll go into more detail and show more example code and live demos.

The second session will cover mobile skinning in-depth. In particular, I’ll cover what’s different between MXML and ActionScript skinning for mobile as well as some of the trade-offs we’ve made in the Mobile theme for performance. I’ll also show examples of how to extend mobile skins and our mobile-optimized item renderers.

Even though it’s only noted in the 2nd session, I’ll likely demo an example iOS-based mobile theme in both sessions as an example of multi-screen mobile skin authoring.

Share on Facebook

Comparing CSS Media Queries vs. Application Scaling

If you haven’t heard of either of these features in Flex 4.5, here’s a quick summary:

  • CSS Media Queries – Conditionally apply styles at runtime based on the DPI and/or OS of the target device
  • Application Scaling – When the application specifies an applicationDPI value, Flex applies a scale factor to the root application. The result is an application designed for one DPI value scales to look good on another device with a different DPI value.

The Flex 4.5 reference covers the differences in the two approaches to adapting a mobile application based on DPI. The documentation also spells out the steps it takes to implement each approach.

Testing both approaches is also straightforward. Flash Builder 4.5 can simulate screen resolution and DPI when you run your application in ADL on your PC. However, it’s not the same as seeing the results on an actual device at the real physical size.

I’ve put together some quick examples to demonstrate each approach and I’ve taken a few photos of actual devices to see the final result. I have 3 devices, going left to right:

  • Motorola Droid Pro, 320×480, DPI Classification = 160
  • HTC EVO, 480×800, DPI Classification = 240
  • iPod Touch 4th Gen, 640×960, DPI Classification = 320

The picture below shows 3 different applications:

  1. Application scaling is turned ON (applicationDPI=160) in the main Application tag. What this means is that I’ve designed my application with 160 DPI devices in mind. Flex will scale the entire application by a scale factor based on the runtimeDPI classification. From left to right you can see 1x, 1.5x and 2x scaling.
  2. Application scaling is turned OFF (applicationDPI is not set). At each DPI, I’ve adjusted my slider to a fontSize value that is readable based on the runtimeDPI of the device.
  3. Application scaling is turned OFF (applicationDPI is not set) but I’ve set single explicit fontSize value that is used for all 3 DPI classifications. Do not do this. As you can see, if you set an explicit fontSize for all 3 DPI classifications, you’ll run into issues at one end or the other. In this case, fontSize 16 is far too small on the iPod Touch.

 

What I should have done in the last scenario is define CSS style rules with media queries that select a proper fontSize based on the DPI of the device. I’ll use a simple label as my next example. The code below has scaling turned off, but this time I’ve defined a stylename with different fontSize values per-DPI classification.

In my ViewNavigatorApplication, I’ve turned off scaling:

<s:ViewNavigatorApplication> <!-- scaling is OFF when applicationDPI is not set-->
  ...
</s:ViewNavigatorApplication>

 

And in my View, I’ve defined a stylename with bold and italic styles that apply at all DPI classifications. After that, I’ve defined overrides using CSS media queries. Notice that I only supplied a new fontSize value for 240 and 320. The first rule is applied at all DPIs. I’m able to omit a 160 DPI-specific rule because it gets it’s fontSize style from the first rule.

<s:View>
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
/* applies to all DPIs */
.heading
{
  fontSize: 18;
  fontWeight: bold;
  fontStyle: italic;
}
@media (application-dpi: 240)
{
.heading
{
  fontSize: 28;
}
}
@media (application-dpi: 320)
{
.heading
{
  fontSize: 36;
}
}
</fx:Style>
...
<s:Label text="Heading Style, fontSize={fontSize}" styleName="heading"/>
</s:View>

 

The photo below shows my app running on all 3 devices. The Label with the “heading” stylename shows the correct DPI-specific fontSize on all 3 devices.

Share on Facebook

Video: How to Skin a TabbedViewNavigatorApplication

Developing skins for the TabbedViewNavigatorApplication isn’t too hard. You just have to know where to start. The diagram below shows the major pieces of a TabbedViewNavigatorApplication:

  1. TabbedViewNavigator – This is a skin part of the TabbedViewNavigatorApplication. The TabbedViewNavigator contains 1..N ViewNavigators. Each ViewNavigator is displayed as a tab in the tab bar.
  2. ViewNavigator – The ViewNavigator is used to push and pop views. Each button on the tab bar represents a single ViewNavigator. In a ViewNavigatorApplication (no tabs) there’s only 1 ViewNavigator.
  3. tabBar skin part – The tabBar skin part belongs to the TabbedViewNavigator. In the Mobile theme, the TabbedViewNavigatorSkin creates this skin part. What’s not so obvious is that this skin part is actually implemented as a ButtonBar, not as a TabBar. The tabBar can be any ButtonBarBase. We chose to use ButtonBar to implement first, middle and last button skins for our default Mobile theme.
  4. ButtonBarButton – Not much to say here. It’s a ButtonBarButton that gets it’s label and icon from the ViewNavigator.

Since the tabs are just a ButtonBar, we could declare a style rule using “s|ButtonBar” as the selector, but that would affect all ButtonBars in the application. Instead, we need to use advanced CSS as follows:

s|TabbedViewNavigator #tabBar
{
  chromeColor: #000000;
  color: #FFFFFF;
  skinClass: ClassReference("skins.TabbedViewNavigatorTabBarSkin");
}

Of course, the major detail I’m leaving out here is the actual TabbedViewNavigatorTabBarSkin. With a little work, I can get my application to look like this:


All it takes is a little bit of FXG and subclassing the existing skins used in the Mobile theme. Watch the video below for a quick explanation, or just download chirpie.fxp and try it out for yourself.

With the June update for Flex and Flash Builder coming soon, knowing your way around the Mobile theme, mobile skins and CSS will help you get started writing cross-platform applications quickly.

Share on Facebook

Tutorial: Styling the ActionBar

The ActionBar appears at the top of your application when you use ViewNavigatorApplication or TabbedViewNavigatorApplication in your project. It’s a skin part in the ViewNavigator that updates as Views are pushed and popped. Since it’s built into the default ViewNavigatorSkin, you don’t normally create it on your own in MXML. Because it’s built in, styling the ActionBar a little less obvious. So, I’d like to show you a few easy ways to customize the look of the ActionBar through CSS.

chromeColor

ActionBar supports the chromeColor style introduced with Spark in Flex 4. This example changes the ActionBar chromeColor to red for the entire application:

<?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.holrHomeView">
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
 s|ActionBar
{
chromeColor: #990000;
}
</fx:Style>
</s:ViewNavigatorApplication>

titleAlign

By default, the ActionBar title is left aligned. To change the horizontal alignment of the title text, set the titleAlign style to left, center or right.

s|ActionBar
{
  chromeColor: #990000;
  titleAlign: center;
}

defaultButtonAppearance

By default, the ActionBar uses flat-styled button skins for Buttons inside the navigationContent or actionContent of the application or view. These buttons are designed to be flush with the edges of the ActionBar.

The ActionBar has two built-in button styles that are controlled by the defaultButtonAppearance style. The second option is a beveled, iOS-styled look seen here:

s|ActionBar
{
  chromeColor: #990000;
  defaultButtonAppearance: beveled;
}
...
<s:navigationContent>
  <s:Button label="Back">
</s:navigationContent>
<s:actionContent>
  <s:Button label="Buy">
</s:actionContent>

Using defaultButtonAppearance=”beveled” is a shortcut for setting several different style values besides the Button skinClass values. These styles include padding, font sizes, and titleAlign.

Advanced CSS Selectors

Setting styles on the ActionBar will cause those styles to be inherited down to title, navigationGroup and actionGroup components. For this reason, the SDK has structured the ActionBar style rules in the Mobile theme to use advanced CSS selectors (see sdks/4.5.1/frameworks/projects/mobiletheme/defaults.css). This is done to isolate styles to specific components and skin parts. For example, you can see that the beveled button skins use a smaller font size than the ActionBar title.

Using advanced CSS selectors does have the drawback of being less obvious to override. Here’s an example of overriding the advanced CSS in the mobile theme to (1) use a normal and italic font for the title and (2) replace the arrow-styled back button in navigationContent with the same skin as buttons used in actionContent.

s|ActionBar
{
  chromeColor: #990000;
  defaultButtonAppearance: beveled;
}

s|ActionBar #titleDisplay
{
    fontWeight: normal;
    fontStyle: italic;
}

s|ActionBar.beveled s|Group#navigationGroup s|Button
{
    /* use the rounded button instead of the arrow button */
    skinClass: ClassReference("spark.skins.mobile.BeveledActionButtonSkin");
}

Next Steps

Use these CSS examples in your mobile projects for quick and easy styling. For more control over the look and feel of the ActionBar, apply your own custom skins.

Share on Facebook

Flex Size and Scaling Issues on the Motorola Atrix

As more and more devices come out, we on the Flex team have occasionally seen platform-specific or device-specific bugs. One of the more visible ones is when flash.system.Capabilities.screenDPI reports the wrong value.

Flex Mobile applications use the screenDPI property for application scaling (when setting the applicationDPI property) or when choosing density-specific skins (i.e. not using the applicationDPI property). When this value is wrong, Flex component skins and layout will either be too big or too small for the screen.

Unfortunately, the Motorola Atrix with AIR 2.6 is incorrectly classified as a 160 DPI device. What you’ll see when running your application is that component skins are too small. The bug is logged as SDK-29999.

Luckily, Flex 4.5 provides a way to override the DPI classification at runtime. The spec for this is posted at http://opensource.adobe.com/wiki/display/flexsdk/Override+Default+Density+Mapping.

For the Atrix in particluar, we’ve attached a workaround to bug SDK-29999 and I’ve posted an example FXP project here. The AIR bug will be fixed in a future release of AIR.

Download: SDK29999.fxp

Share on Facebook

How To: Use Flex 4.5 with AIR 2.5 on the BlackBerry PlayBook

Update: Troubleshooting “AIR validation failed” message. See below.

Update 2: Using Flex 4.5.1 on the BlackBerry PlayBook

Update 3: RIM has announced BlackBerry Tablet OS 1.0.6 with AIR 2.7. The workaround mentioned below is no longer required.

As you might already know, the BlackBerry PlayBook from RIM will initially be shipping with AIR 2.5, not AIR 2.6 (this is to come later in an update to the device). Flex 4.5 SDK requires AIR 2.6 as the minimum supported runtime – this is because of specific feature support (such as soft keyboard) as well as bug fixes/performance improvements. We know however that a lot of you are eager to develop Flex 4.5 applications for BlackBerry Tablet OS, so I’d like to share an unsupported workaround that you can use in the meantime.

I’ve created a playbook_overrides.swc that monkey patches the release build of the Flex 4.5 SDK to remove all AIR 2.6 dependencies. This allows you to publish a Flex 4.5 application that targets AIR 2.5. Here are some instructions to get you started. Again, keep in mind that this is an unsupported hack until (1) AIR 2.6 is available on the PlayBook and (2) Flex and Flash Builder update to 4.5.x in June 2011.

Requirements

  • Flash Builder 4.5
  • BlackBerry Tablet SDK and Plugin 1.0.1
  • playbook_overrides.zip (Contains playbook_overrides.fxpl, playbook_overrides.swc and TwitterTrendsFinal.fxp example project)

Steps

  1. Create a new Flex Mobile project with BlackBerry Tablet OS as a target platform
  2. Add playbook_overrides to the library path. This SWC patches SDK and Mobile Theme classes to remove soft keyboard dependencies. Download: playbook_overrides.zip
  3. Open Project Properties > Flex Compiler
  4. Add “-swf-version=10″ in “Additional compiler arguments”
  5. Open Project Properties > Flex Build Packaging > BlackBerry Tablet OS > Advanced tab.
  6. Add “-forceAirVersion 2.5″
  7. Run/Debug to device or emulator

Troubleshooting

  1. Crash on launch (application briefly appears in launcher, then closes).
    Make sure -swf-version=10 is set in additional compiler arguments.
  2. Blank or stuck on splash screen on launch
    Usually indicates a runtime error. Could indicate an AIR 2.6 dependency VerifyError.
  3. Error dialog when packaging: “error 102: invalid namespace http://ns.adobe.com/air/application/2.6.0 Error: AIR validation failed”
    Change the namespace in your /project/src/project-app.xml from “2.6.0” to “2.6”

Next Steps

  • Refactor your project into 2 projects to target Android with AIR 2.6 support and BlackBerry Tablet OS with AIR 2.5 support simultaneously
  • Use the BlackBerry Tablet SDK for native controls in your Flex Mobile project
  • Try the TwitterTrendsFinal.fxp in the playbook_overrides.zip. This FXP already links playbook_overrides.swc and is ready to deploy. All it needs is an update to blackberry-tablet.xml to add the <author> and <authorId> of your debug token to deploy to a PlayBook.
Share on Facebook