Developer Week – Multi-Density And Multi-Platform Authoring

5 downloads 3242 Views 7MB Size Report
the screen size, the font looks good on the iPad on the left and looks way too small on the. iPod on the ... classifications Flex has 2 strategies for developing for screen density. The first .... check out my Adobe Developer Center articles. Next up ...
An hour isn’t a lot of time to cover every topic on multi‐density and multi‐platform  authoring. So, my goal for today is to cover the core principles that are built‐in to the Flex  SDK and show some simple examples of how to apply these techniques.

1

The fundamental problem with different pixel densities is that they change the physical size  of your UI elements. For a given pixel size, a UI element like a button displayed on devices  with higher densities will become too small to accurately target with a finger. Let’s look at  an example of a 150x40 pixel button. (step through each size)

2

Here’s just a small sampling of phones and tablets and the wide variety of screen sizes,  resolutions and DPI values.

3

Especially when it comes to mobile devices, all pixels aren’t created equally. You shouldn’t take exactly the same content and visuals you have in your desktop apps and simply drop  them into a mobile app. You can see a lot of bad examples of this, especially on an Android  phone when running older, unoptimized Flash content in the browser that was intended for  a desktop mouse and keyboard experience. What you have to start to think about is the position and size of any on‐screen element  relative to the DPI of the screen. Failure to address screen density will result in applications  that look either too big or too small on many mobile devices. (Reference bullets).

4

Here’s a really simple example of where sizing can go wrong quickly. All I’ve done here is set  an explicit fontSize in my MXML and I’m running the same application on an iPad at  approximately 160 DPI and an iPod 4 at approximately 320 DPI. You can see that relative to  the screen size, the font looks good on the iPad on the left and looks way too small on the  iPod on the right. So, how does Flex address these issues? (Next)

5

Essentially categorizes mobile devices into 3 different buckets. Think of them as low,  medium and high density at 160, 240 and 320 DPI respectively. Based on the 3  classifications Flex has 2 strategies for developing for screen density. The first one is the easiest one: application scaling. You simply specify a target and design  for a specific DPI, then Flex will scale your application up or down based on the device. The second option requires more work: density specific skins and styles. With this option,  you create (as necessary) graphics and size‐related styles for each skin, and choose the  appropriate the correct graphicsand styles based on the DPI.

6

Before we dig into the 2 screen DPI solutions, I want to introduce the tools that we’ll be  working with. First is MultiDPIBitmapSource. This MXML component lets you explicitly design 3 different  bitmaps to use, one at each DPI. You would use this instead of scaling a bitmap at runtime  to avoid scaling artifacts. Next is the applicationDPI property. This is what switches application scaling on and off. It is  at the center of all DPI‐based features in Flex mobile projects. And the last tool we’ll look at is CSS media queries. This new CSS syntax allows you to  enabled and disable style rules, at runtime, based on the screen DPI and the device OS. The simplest feature 

7

The main way we recommend, which should work for most cases, is to use automatic  scaling. You turn this on by setting the applicationDPI attribute on your application tag  (either Application, ViewNavigatorApplication, or TabbedViewNavigatorApplication). In this  example, we’ve set it to 160. This doesn’t mean that our application will only work at 160  DPI. What it means is that the application will apply a scale factor on the X and Y axis and  essentially change the screen resolution available to your application when the device does  not match the targeted applicationDPI. For example, if you have a 160‐pixel‐wide button in your app (which would be 1” wide at  160 dpi), and you run your app on a 240 dpi device, Flex will scale the whole stage by 1.5x,  so your button will now actually be 240 pixels wide on the device. This means that it will  stay 1” in width.  The net effect of scaling up is that while you have less resolution available, but your entire  app is now scaled to look good on the higher DPI screen. Note that because this is applied by scaling the entire app, your code actually isn’t aware of  any scaling. If you were to query the width of this button at runtime on a 240 dpi or 320 dpi  device, Flex would still report the button’s width as 160. As far as you’re concerned,  everything is at 160 dpi, no matter what actual density device you’re running on.

8

Here’s an example of an application with scaling turned off on the left, and on the right is  the same application but with scaling turned on. The screen shot on the right is scaling  from 160 DPI To 240 DPI. The most obvious way to think about scaling is that pixels grow in size based on the scale  factor. When running an application targeted at 160 DPI on a 240 DPI screen, pixels are  scaled up by a factor of 1.5. A less obvious way to think about scaling is that the screen dimensions shrink by the scale  factor. (animate) You can see on the right that the width of the screen shrinks from 480 to  320. (animate) Also, note that you can still get the actual pixel size of the stage by accessing  stageWidth and stageHeight.

9

In summary, to use scaling (talk to bullets) • When applicationDPI is missing, scaling is not enabled • We’ll talk about how bitmaps scale in a few slides

One potential drawback when using scaling is that there can be visual artifacts.  When the scale factor is not an integer (for example, when scaling up 1.5 times  from 160 to 240), this can cause visual artifacts (in some cases) with vector artwork.   This is because Flash aligns strokes on their center. In FXG, a sharp 1px stroke line should start at a half pixel coordinate (0.5,0.5). When this  line is scaled up 1.5x to 240 DPI, there will be some subtle blurring of the stroke above  and/or below the center of the line.

10

The alternative to scaling is to explicitly tailor skins, graphics and/or styles for each DPI you  support in your application. A good example of this technique is the mobile theme included in the SDK.

11

12

13

14

Text and Bitmaps are generally not a concern. Text should not exhibit any artifacts  because text is scaled by scaling the font size value rather than scaling the actual  vectors. For example, if you use fontSize=16 with a target DPI of 160 on a 240  device, internally, Flash player scales the font to 24. Bitmaps should not exhibit scaling artifacts when using MultiDPIBitmapSource to  specify appropriate bitmaps for each DPI. We’ll talk about this feature next. In practice, the Flex team has found only minor visual differences between using  160 DPI skins scaled up to 240 DPI and using 240 DPI skins unscaled. For most  applications, this approach should work well, and you can stop reading right here.  However, if you find unacceptable visual artifacts form scaling, or have other  reasons why you need more detailed control over the behavior of your application  at different densities.

15

(A lot of this was covered already. Ok to gloss over this slide and notes and just emphasize  bitmaps) Note that in our examples so far, we’ve been targeting 160 dpi and letting the application  scale up. This may seem counterintuitive, since it’s usually better to scale down rather than  scale up. What we’ve found is that vectors generally scale up better than they scale down. When you  scale vectors down, you tend to get artifacts like misalignment. Scaling up generally works  well, although you might get some slight blurring of strokes which we’ve covered already. Text scales well in either direction, because when Flash Player/AIR scales text, it doesn’t  scale the actual vectors—instead, it just calculates a new font size, and then renders the  text directly at that font size. So there’s no artifacting. Bitmaps, however, don’t scale up well, as you know. You might think scaling down would be  a better solution, but that has two problems: it tends to blur the bitmap, and it also means  that the runtime has to downsample the bitmap, which is an extra performance hit you  don’t want on a mobile device.

16

To help with bitmaps, we’ve added a MultiDPIBitmapSource class that you can use  anywhere you would ordinarily specify a bitmap source—for example, an Image or  BitmapImage source, or the icon of a button as in this example. You simply create different  bitmaps for the different densities, and Flex automatically uses the correct bitmap at  runtime. It also takes care of transforming the bitmap appropriately while the rest of the  application is being scaled so that the bitmap actually shows all its pixels, instead of being  downsampled and re‐upsampled or something weird like that. Creating bitmaps for use in a MultiDPIBitmapSource is simple—just figure out how big your  icon needs to be at 160 dpi, and then create 1.5x and 2x larger versions for the other  densities.

17

Since we just talked about application scaling using applicationDPI, you might be asking:  How application scaling interacts with MultiDPIBitmapSource? The answer is, it works  exactly as it should. When scaling is in use, Flex selects the bitmap designed for the device’s  DPI and applies the correct transforms such that the bitmap appears unscaled. Normally, you would have the same content in each bitmap, but adjusted for more or less  detail based on the DPI. For the purposes of this next demo, I’m putting pre‐rendered text  for 160, 240 and 320 in the bitmap to show exactly which bitmap is being displayed. It can  be confusing to understand the combination of scaling (at the application and in the  image). 

18

Here are my original bitmaps at full size. I’ve sized the original bitmaps at 320px wide,  480px wide and 640px wide to make the math easier.

19

With scaling turned off, you can see that the MultiDPIBitmapSource selects the correct file.  I’ve added some text below the image to show the applicationDPI to verify that scaling is  off.

20

Now here’s the same application, but with scaling turned on. If you don’t see a difference  from the previous slide, that’s because there’s effectively no difference. When scaling is  turned on, the SDK knows how to select the correct bitmap from MultiDPIBitmapSource and also knows how to transform the bitmap to its natural size while the rest of the  application is still scaling.

21

For apps that I’ve published personally, I’ve gone with the density‐specific approach as  opposed to scaling. I want full control of my graphics and the sharpest edges on my strokes. That wraps up the density‐related features in Flex. There’s other topics that we could cover  like a DPI specific splash screen and authoring DPI‐specific FXG graphics. For those topics,  check out my Adobe Developer Center articles. Next up are a few tips for handling platform‐specific issues when authoring mobile  applications.

22

There are still a lot of desktop users out that that groan when they run into a Flash  application or an older Flex 3 web application that obviously doesn’t behave like HTML in a  browser. On the other hand, there are a lot of successful, non‐native skinned applications  out there like TweetDeck. Success with non‐native UI really depends on design and  execution. Other reasons to tweak your design based on the platform are to optionally add a Back  button to your UI when not running on Android.  Also, as we saw on the last slide, device fonts across platforms have enough nuances that  you might want to tweak some parameters for a more consistent look or size. If you choose to add some platform specific changes to your app, you have 2 basic options  when coding.

23

Here’s a simple example of how facebook accommodates for Android vs. iOS.  Style‐wise, iOS apps use center‐aligned titles, and they use pretty standard gradient  parameters in the ActionBar as well. Also notice the style of the buttons in the ActionBar.  Android has a flat‐look that’s flush with the edges of the ActionBar while iOS has beveled  buttons that look like they’re slightly pushed into the surface. iOS applications typically  have just one button in the right‐hand side of the ActionBar. Functionality‐wise, the Android app hides the account button in the menu when you press  the menu button. 

24

Here’s another example of platform‐specific styling. iOS apps have tabs on the bottom  while Android apps typically have tabs on top. Also, notice that there’s a back button at the  top of the iPhone app, but the Anrdoid app doesn’t have one since Android phones have a  hardware back button.

25

Buttons • On Android, apps can use back, menu and search • On iOS, no hardware button access except volume. Most iOS apps add a back button in  the ActionBar when there’s history to go back to. • On PlayBook, swipe down menu Typography • Device fonts at the same size and DPI classification may be less readable Text input • There are unique challenges when dealing with the player’s built‐in TextField on mobile.  I don’t have enough time to cover them here, but I will cover them in my session on  Friday about creating performant skins and item renderers for mobile applications at  11am pacific time.  • One thing I will point out quickly is that on iOS, when editing text in a TextField, this is  done completely in a native iOS control. In a demo later, you’ll see that text selection,  cut/copy/paste, and the clear button are all present just like a native iOS app. Color depth: Android limited to 16‐bit

26

The screenshot here might not be obvious to everyone. But to be clear, each device has a  different default sans serif font.  When targeting multiple screen sizes and devices, you should be prepared for some  truncation or overflow. This mindset is similar to working with localized strings of various  lengths.

27

Now that we’ve discussed some platform specific issues, you might want to add some  platform specific logic to your code. You can do this in CSS and in ActionScript. Here’s a CSS example using media queries to wrap a style rule that will only be effective on  iOS. (discuss os‐platform values: ios, android, qnx (playbook))

28

In ActionScript, you can use flash.system.Capabilities.version to determine the platform at  runtime.  (discuss Capabilities.version “IOS” “AND” “QNX”) You can even get more clever and use this technique with MXML states to do platform‐ specific logic using MXML’s declarative markup. There’s a missing 3rd option that I haven’t mentioned yet. Basically, you could create a unique project for each platform you support. You can of  course share code between projects, but in the end, each project produces a unique binary  that’s only intended for one platform. This way, instead of checking the platform at  runtime, you already know your target platform at compile time and when you package  and distribute your application.

29

Here’s an example of using CSS media queries to set different styles based on the platform.  In this case, for iOS I’m using the ActionBar beveled style to give me iOS‐like buttons. The second rule applies to all platforms. This rule specifies the light blue chrome color.

30

Here’s another example of a custom ViewMenu skin that’s made to look like iOS. Elsewhere  in my app, I specified the skinClass for the ViewMenu to be iOS specific. The code I’m  showing here adds some different colors on iOS only. Then on Android, I add icons to the  ViewMenuItems.

31

The last 2 slides show how you can adapt your application per‐platform if you choose to.  It’s not the right solution for everyone. Some customers might prefer a heavily branded  experience that’s consistent across devices. Luckily, with Flex skins and CSS, you have the flexibility to do either approach. The last thing I want to show you before I wrap up is an example of how far you can take a  native looking theme. Keep in mind this is all using 1 code base and essentially 1 project  using CSS media queries and lots of custom skins. The main logic of my application is  shared for all platforms.

32

33

34

I just want to point out a few good follow on topics to this skinning session. They’re both  on Friday. The first is at 9am pacific. Evtim is the speaker and he’ll be talking about  performance in general across mobile and desktop. The second one is at 11am pacific and will be my second session. I’ll talk specifically about  performance optimizations that are implemented in the mobile theme skins. I’ll go  through, step by step, how to create a mobile‐optimized skin based on the MobileSkin base  class. And finally, I’ll talk briefly about performance considerations for item renderers and  how to use the built‐in mobile‐optimized item renderers in Flex 4.5

35

36

37

38