Resolution-specific graphics in Titanium

By | March 25, 2015

Working on an app the other day, I came across some complex logic for selecting which graphics to show on an iPhone 5 vs. an iPhone 6 vs. and Android device. While it worked, it didn’t capture all possibilities and frankly, was totally unnecessary. In the end, I replaced 30 or so lines of if-then branching code with three simple image assignments.

Let’s break it down into two parts: iOS and Android

iOS

You probably already know that you use a special naming convention for iOS splash (launch) screens. It goes something like this:

  • Default@2x.png (640 x 960) for retina iPhone 4s
  • Default-568h@2x.png (640 x 1136) for iPhone 5
  • Default-667h@2x.png (750 x 1334) for iPhone 6
  • Default-736h@3x.png (1242 x 2208) for iPhone 6 Plus

Each file has a base name (Default) and extension (.png) as well as a device/resolution-specific suffix, such as -568h@2x. Well, you can use that same naming convention for any of your graphics.

Let’s say you have an image, myimage.png, for which you want to provide device-specific versions. You’d create appropriately sized and scaled images for each of the device classes and you’d name them myimage@2x.png, myimage-568h@2x.png, myimage-667h@2x.png, and so forth. In your code, simply use:

"#myimage": { image: '/myimage.png' }

That’s it. iOS will select the right image file to use based on the device that’s running your app. (Make sure to put these images in app/assets/iphone so that they’re not included in your Android builds.)

Android

Android also has a notion of images specific to various device classes. But rather than using suffixes and dumping all the images into the same folder, you put images with identical names into a set of folders.

In app/assets/android/images, you’ll find a set of folders created by the Titanium tooling. You can use them if you want to be specific about resolution, orientation, and screen shape. But, for most in-app graphics, you’ll want to create a new set of folders inside app/assets/android/images:

  • res-ldpi (if you support low-DPI devices; you can probably skip this)
  • res-mdpi (medium, or 160 dpi)
  • res-hdpi (high, or 240 dpi)
  • res-xhdpi (extra-high, or 320 dpi)
  • res-xxhdpi (extra-extra-high, or 480 dpi)
  • res-xxxhdpi (triple-X-high, or 640 dpi)

Again, you’d create the myimage.png size in the various sizes/densities. You’d put each version into the appropriate app/assets/android/images/ subfolder, but make sure to call each myimage.png.

In your code, again simply use:

"#myimage": { image: '/myimage.png' }

That’s it. No branching code,Ti.Platform.displayCaps.platformHeight calculations, or custom TSS selectors.

Note: Android probably won’t display your graphic if you omit the leading slash. iOS doesn’t care. So, save yourself some headaches and always begin file references with a slash.