Sunday, April 1, 2012

How to scale your Android layouts to Tablets and small devices (ALASCA)



One of the great things about Android is the flexibility in the way it handles layouts. On similar phones with different pixel-resolutions, you can make the layouts stay proportionally consistent. This gives device makers freedom to work out the perfect screen and consumers broad choice among the flavors.

But what you as a developer might have realized, defining layouts to fit ALL devices is more complicated than that. When you make your app by following good layout practice, and happily test it on your normal phone (Nexus S for example), everything might look right. But when you try it out on a tablet (like the Galaxy Tab) or a small screen device (like the X10 mini), the layout might be cut off in some places or scaled wrong. This is because the densities of tablets and small devices fall into different "density-buckets". There's four of these density buckets: small, normal, large and xlarge. And your layouts will likely need to be adjusted to fit them all.

So without further ado, I have made a tool to do just that. The tool will scale your layouts to look proportionally good on tablets, small screen devices and everything in between. All you have to do is use density independent pixels (dp units) in your layout files, define your base-line density and define your new target density. Also... click a button.


The tool

I've called the tool ALASCA - The Android Layout Scaler. It's a simple java application with a graphical user interface. Choose your multiple xml layout files through the FileChooser, define your base width and height (the dp values you have currently designed for), and define your new dp-target width and height.

The stand-alone executable: https://github.com/OneManMobile/ALASCA/raw/master/ALASCA.jar

The source code: https://github.com/OneManMobile/ALASCA

The tool is so simple that it should only take you very few minutes to have your app ready for tablets and small devices.

When you have selected your parameters, just press the "Create New Layouts" button and the tool will generate a new layout folder with the name "layout-[some number]" in your current files directory. Like this:




Use the new "layout-[some number]" folder and put it into your project. Rename the folder to "layout-small","layout-large" or "layout-xlarge" to reflect the density that the new layout files are scaled for. Now, any Android device will automaticaly choose the files from the density that fits its screen.


How to make the tool work right


Have every size value defined in dp units. You can use "fill_parent" and "wrap_content" like before but any padding, margin, specific width, specific height and textSize should be defined in Density Indepenent Pixel units (dp).

Find the magic values for scaling, these are mine from practical experience but use an emulator-device and set "abstracted LCD value"  if you want to double check different densities:



- Small: 310 dp x 410 dp (Emulator tested on 120 abstracted LCD value) 



- Normal: 320 dp x 510 dp (I know I've read 480dp for height, but this works on at least Samsung Galaxy S2, LG Optimus 2, Nexus S and HTC Desire from my experience)


- Large: 540dp x 960dp (Update: 540 x 880 on Nexus 7 seems to work well)

- XLarge: 800 dp x 1255 dp ( (Tablets: I've read 1280dp for height but this works on Galaxy Tab 10.1 in my experience)

For example, take the base width and height of 320 and 510 and set the target width and height to 800 and 1255 respectively. Then fire off the layout creator.

I apologize for the shifty height values, which aren't really mentioned anywhere as standard, but these are the ones working from my personal experience.

Note: To make sure both width and height is scaled properly, the tool expands "android:padding=XXdp" and "android:layout_margin=YYdp" into their four sub-definitions for left,right,top,bottom in your new files.

Points to remember on good scaling


ALWAYS use density independant pixel ("dp"/"dip") units in your layout files. "Px" units are only for a specific resolution, density is not accounted for, and should generally never be used. "Sp" units are used when you want to take font size user-preference into account, but a variable text size generally leaves unpredictable design complications.

When creating your own Custom Views, always remember to have your length units defined relative to the pizel-size aspects of the view (not the density of the device). So in your onDraw method, use getWidth and/or getHeight as base for the scale-factors of any measurements and placements you want to make. This will make your custom view look awesome on tablets.

And so..


This was my first blog post, and it was about a problem that I'm still not completely sure I should have solved. Maybe I have missed something in the documentation that handles this issue or maybe others can benefit from what I made. If you have any feedback on the project, feel free to give it. If what I made is useful, perhaps we will soon see a lot more tablet optimised apps out there.

Special mentions: Mobile Identity, the company I work in - Jesper Borgstrup, a fellow android developer, who provided a tablet (Galaxy Tab 10.1) for testing and inspiration - The experience I've gotten from my personal app projects.


 TL;DR - Create layouts for one density, have them scaled automatically for tablets, small devices and everything in between.


15 comments:

  1. how to use thi..

    ReplyDelete
  2. Its very easy and helpful thanks , der is any image converting tool for different devices...

    ReplyDelete
    Replies
    1. Hi, thanks!

      Image conversion tool? The size of images are defined by the views that holds them. Their quality are determined by the screen type. Which means you can put images in "drawable-hdpi", "drawable-mdpi" or "drawable-ldpi" folders and the right image quality will be selected for the right device.

      Can you be more specific if I'm not on the right track?

      Delete
  3. can you suggest me which layout to choose for my android app for supporting multiple screen sizes.

    my requirement is simple login, signup and show user data and no more design needed.

    im newbie to android.

    Thanks,
    Prasad.CH

    ReplyDelete
  4. Hi, I'm having a problem with regards of setting a valid integer value. Is there any problem with my XML files?

    Thank you.

    ReplyDelete
    Replies
    1. Hi

      I apologize if this is the error, but you may just have snuck in a whitespace character when assigning widths and heights? Or maybe put a decimal in there?

      The interface could be more robust, and will be if I upgrade it one of these days.



      Delete
    2. (defining base-width and base-height, or target-width or target-height in ALASCA by the way)

      Delete
  5. Hi Andreas,

    great tool! I love it. Takes away the tedious task to manually update and keep in sync those different layout directories. Only thing I have added to also replace textWidth in sp ... awesome tool.

    Thanks
    Michael

    ReplyDelete
  6. great tool. Many thanks. Wish you good luck in future

    ReplyDelete
  7. i dont understand how you choose the base and target numbers...
    i have nexus 4 so what is the target number?

    ReplyDelete
  8. i do want set layout for all devices... and how to create.
    pls help me...

    ReplyDelete
  9. how to use this help me ..i got a new job in android and i really need that but i still dont understand that concept help me out thanks

    ReplyDelete
  10. tool is not running.....my os is windows 7 just it says could not find main class and exits.

    ReplyDelete