Thursday, July 24, 2014

Support for building apps on API Level 4 in App Inventor - Better Tablet Support

We've been working to take App Inventor out of screen compatibility mode, and that work has now been merged. This hasn't made it to a release yet, but it will soon. We will announce the changes in the forums when this happens.

What does it all mean though?
For starters, App Inventor will not support Android 1.5 (API level 3 - Cupcake) anymore, but we are compiling against Android 1.6 (API level 4 - Donut). We know there aren't a lot of devices out there still working at this level, but the change from level 3 to 4 was a rather large step to take, mainly because of the already mentioned screen compatibility mode.

Up to now, all App Inventor apps would be automatically scaled by the system to make them look the same in all devices, no matter their resolution or screen size. This sounds good, but the effect of this was that most elements would look rather awfully oversized on bigger screens such as tablets.  From now on, the resolution of the device will be used, and apps will look much better in larger screens with higher resolutions. As a drawback, the App Inventor designer will be a bit less in sync with what's actually being rendered on the device, but we've done our best to keep things as smooth as possible. If you find any issues with rendering in the designer please do get in touch with us through the forum.

What other changes have been made?
We have added a check to change from Tablet to Phone preview mode. It basically resizes the viewer so that you can see how the app looks at two different sizes. We are using Nexus sizes as generic here, Nexus4 for phone, and Nexus7 for tablet. As you can see in the screenshot below, we have also added the buttons bar found in most newer devices. The two changes are highlighted in red.

Another big change is that now all sizes for elements are density-independent pixels (DP) instead of hardcoded pixels. You will see a change in the Width and Height boxes in the designer.

The concept of DP is a little hard to grasp. Some people compare it to using percentages for sizes in HTML, but that's not quite correct. This is the definition used in the main Android docs:

Density-independent pixel (dp)

A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way.
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple:
px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.

This DesignBytes video by Roman Nurik is a good source of information about the topic:

There is an additional property that has also been added to Images: scaleToFit; checking this box you can make an image fit completely the size of its enclosing area, for instance if you fill the parent in width or height, the image will fit the area (the image will not keep its aspect ratio, so be mindful when using this property).

So, with all these changes, what are the things to watch out for?
Some apps might be affected, especially those using hardcoded sizes in pixels. We have made many tests and the majority show very little differences, but there might still be some differences.
The other thing to watch out for is if you were using any tricks to grab the height and width of the screen to size your elements. Watch out for problems in there and please report whatever you find.

And what's next then? Well, this change opens a number of possibilities for App Inventor apps. We can start thinking about using a targetSDK level now, even providing a property in Screen1 to allow the user to choose which level that is. We could also start thinking about moving to API Level 8 (Froyo) as there are not many devices using a level lower than that. But probably the most important change here is that we can now start using support libraries and think about adding some of the most used design patterns in Android, such as Action Bar, navigation patterns, or even themes.

This is all a bit far ahead, but there's no technical reason stopping us now from working on changes like those. If you want to help with any of these projects, do get in touch through the open source forum. Great times ahead!