Thursday, May 31, 2012

Eclipse ADT: Conditional Breakpoint Error

When I tried to understand the way Android's RelativeLayout measures and re-sizes the views it contains, I had do debug the Android SDK sources. Eclipse makes that quiet easy. All you have to do is attach the sources of the SDK you are using to the «android.jar» in your project's preferences.
Stepping through the source and setting breakpoints worked flawlessly. But when I wanted to set a conditional breakpoint (because I wanted to stop execution when RelativeLayout.onMeasure measured a specific sub-view), Eclipse failed with an error:

Conditional Breakpoint Error

It reads: «Conditional Breakpoint Error. Conditional breakpoint has compilation error(s). Reason: Unable to compile conditional breakpoint - missing Java project context.» Also, evaluating and displaying Java expressions would not work and gave the following error:

Error Evaluating

It reads: «Error Evaluating. Unable to evaluate the selected expression: To perform an evaluation, an expression must be compiled in the context of a Java project's build path. The current execution context is not associated with a Java project in the workspace.» Evaluated expressions come in handy, for instance, when picking the MeasureSpec of a View apart, which is a bit-field composed of a length and a mode.

Searching the internet for a solution, I only unearthed the rather vague suggestion to—surprise!—create a Java project for the Android library sources. I was not really fond of that idea, subdued by the size of the library. Not without reason, as I saw later. So I asked for a solution over at stackoverflow.com, but to no avail. I suppose the problem is to specific. When nothing came out of it, I had to swallow the pill and create a project for the sources of the Android library. And guess what? It fixed the problem!

Step by step do the following. First create a new Java project. A wizard dialog will pop up. Name the project as you like, «Android library sources» seems appropriate. On the next page, link an additional source and point it to the appropriate source directory in the Android SDK. Eclipse will now ask for «Inclusion and Exclusion Patterns». Exclude everything by adding the asterisk «*» to the exclusion pattern. This both surprising and important. Surprising because Eclipse does not need to do anything with the sources (like compiling) for conditional breakpoints and the like to work. And it is important, because otherwise your log will overflow with warnings, and error and info messages. Finish the dialog.
Now you need to attach the source code to the «android.jar» library of your project. Open your project's properties. You will find the library under «Java Build Path» on tab «Libraries» as show by the following screen shot:

Attaching the source code to the Android library

I my original configuration I had attached the source from an «External Folder» instead of a workspace, which only worked partway.

And that's it!

Thursday, May 24, 2012

Android ImageView and BitmapDrawable: gravity and scaling to fit

This article explores whether it is possible to display a square picture (for instance the cover of a music album) in a way that it uses the whole width of the display and keeps its aspect ratio. No programming must be involved, i.e. a pure XML-layout definition is the goal.

The problem of proportional scaling

Milestone 1 of my journey into Android software development is creating a rudimentary GUI for a MP3 player app. On the way towards it I soon ran into a first problem, naturally. The cover image (in the mockup represented by compact disc) would not display as intended. It was supposed to fill the screen width, scaling proportionally in height (assuming square dimensions of the cover and portrait orientation of the phone). And though the BitmapDrawable scaled (down) correctly, the enclosing ImageView would never wrap it up in height. In fact, it would be so large that it even pushed the SeekBar out of screen:


Dream (left) and reality (right): the ImageView does not adjust its height to the picture of the compact disc. Its actual dimensions are marked by the blue border!
My first attempt to layout the ImageView is shown by the following code snippet. The cover image sits inside a RelativeLayout (not shown) and is aligned below the song title (line 5).

<ImageView  
       android:id="@+id/cover"  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:layout_below="@id/songtitle"  
       android:src="@drawable/cd" />  

I assumed that setting layout_width to to «match_parent» would scale the image to fit in width, which it seemed to do. Furthermore I assumed that setting layout_height to «wrap_content» would shrink the view closely wrap the image, i.e. would result in a ImageView of square proportion. It did not, obviously.

I am not going to retrace in detail how I went trial-and-error through the numerous properties of the Drawable and ImageView classes. Lets approach it more systematically, because there is more than a single factor in effect here. The source code for this project is available at GitHub. I will created tags for each point discussed in this blog.

For this experiment, I created three square images of varying dimensions: one too small for a WVGA800 screen (which is 480×800px in the case of the Galaxy S2), it is 100 pixel wide and tall; another of exact fit (480px wide); and a third images too large for the screen (800px wide). The vanilla layout looks like this for these three image sizes:

Android prevents clipping of over-sized images and rather scales them down. The blue border marks the bounds of the ImageView.
Only for the picture which is too small for the screen the ImageView behaves as expected (by me, at least). For both the exact fit and the over-sized picture the ImageView does not wrap its content. Android also scales down the over-sized picture to fit the screen, which is a sensible precaution. The small image however is not enlarged automatically, probably because it a) might look terrible, b) does no harm to leave it as is.
Now lets play with the properties of the user interface components.

BitmapDrawable gravity (and tiling)

Poking around the API documentation, I first stumbled upon the gravity attribute of the BitmapDrawable class. It looked promising, offering options for pushing a picture toward any edge of the container, or scaling it, or clipping it. Surprisingly, none of the options had any effect on the scaling and placement of the sample images from above. For both of the larger images the API documentation might explain:
The gravity indicates where to position the drawable in its container if the bitmap is smaller than the container.
But why then does it not work for the small image either? It turned out, that the phrase «in its container» misled me. The source code of BitmapDrawable.draw(Canvas) reveals that gravity only applies within the bounds of the BitmapDrawable itself. The ImageView sets these bounds via Drawable.setBounds(int,int,int,int) to the exact dimension of the underlying bitmap image. There is only one case in which the bounds actually matches the proportion of the ImageView and this is when ImageView.scaleType==FIT_XY («fitXY» in a XML-layout) in the private method ImageView.configureBounds().

The scaleType of class ImageView defaults to «FIT_CENTER». To make use of gravity, it must be set to «fitXY». Furthermore the src-property of the ImageView must refer to a bitmap XML-definition and not to an image file (res/layout/toosmall.xml):

<ImageView
    android:id="@+id/cover"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/songtitle"
    android:scaleType="fitXY"
    android:src="@drawable/toosmall" />

Then the gravity of the BitmapDrawable can be configured with something like this (res/drawable/toosmall.xml):

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/square100"
    android:gravity="fill_vertical"
/>

That means gravity only affects the appearance of the picture if the bounds of the Drawable are actually larger than the physical dimension of the picture displayed. Apart from ImageViews with ScaleType.FIT_XY this is the case for View backgrounds. Best use an empty, fully expanded LinearLayout for experiment, as I did for the following screenshot.

As background image, a DrawableBitmap receives enough room for gravity and tiling to have an effect. From left to right: gravity="right|center_vertical", gravity="fill_vertical", tileMode="mirror".
The gravity property has further oddities. Especially the properties clip_vertical and clip_horizontal behave completely opposite to intuition as +Lorne Laliberte points out.

ImageView scaleType and adjustViewBounds

The scaleType has a major say on the placement of a Drawable inside an ImageView (read the Andre Steingress' blog posting on its various effects). But disabling scaling via «fitXY» in order to make gravity take effect will not solve the problem of the view area being larger than the contained bitmap! No combination of gravity flags will scale the bitmap proportionally! So gravity was a red herring after all. It is the property «adjustViewBounds» in combination with the default scaleType that will do the job.
[Update 2012-05-25]: When adjustViewBounds is true, the scaleType no longer matters: ImageView will reset it to FIT_CENTER (the default) anyway.

The adjustViewBounds property will shrink the ImageView to fit its content. it has unwanted side-effects, though.
Now cry «cheat!» The larger images look fine, but the small image stubbornly retains it dimensions, and is not scaled to fill the width of the screen. Unfortunately, there seems to be no way to fix this by a XML-layout definition alone, programming is required, and I am defeated for now. I will explore the different approaches in a later posting.
If someone knows a way to archive it by pure XML, I would be grateful to hear about it!

Conclusion

There seems to be no way to proportionally scale an ImageView to match its parents width by means of a XML-layout definition alone. Bitmaps which are larger than the available display space will be reduced in size correctly but smaller images never enlarge proportionally. The most obvious solution would be to provide fitting or over-sized bitmap images for each targeted device. But this is neither future-proof nor always possible—think of the cover images which usually come in just one size, attached to a MP3-file. But then again, dynamically loading images always requires some programming anyway. So a few extra lines of code might not matter too much.

Monday, May 14, 2012

Drawing an Android mockup with Inkscape and GIMP


First stop on my journey into mobile app development is creating a basic graphical user interface (GUI) for the MP3 player app. The GUI needs neither to be useful nor slick, not even functional. The only requirement is, that it must execute on a real phone. That should give some insights into GUI construction with the Android SDK.

Programming a user interface is not very complicated, especially if the GUI is mostly static and uses stock controls. Visual GUI construction tools, like the one that comes with the Android SDK, enable designers to layout the user interface without having to write a single line of code and leave it to the programmer to bring their vision to life. In fact an adept designer can rearrange the layout right before the eyes of the customers to meet their requirements—If he is proficient with the tool!
For a beginner these tools are still to complicated. In fact, even designers might shun them for the very same reason and confine themselves to all-purpose graphical tools like Adobe Photoshop or specialized tools for mockup design.

The mockup the designer draws might look identical to the actual application the user sees, but they are in fact structured quiet differently. The designer stacks various shapes, bitmaps and chunks of text on a grid. And though he arranges these elements in relation to one another, the relation remains implicit in the design. Each element is fixed in position and size. And while the same can be done when implementing a user interface, it is deprecated by many platforms. The reason is that unlike the real program a GUI mockup needs not be functional, adapt to different display proportions or resolutions, and need not accommodate variable data, like text of varying length. It must never execute on a computer. They merely aid negotiating an appropriate screen layout with the various stakeholders. It is okay that they are only an illusion.
In a computer program the relation of the user interface elements need be represented explicitly. This makes using visual GUI construction kits different from graphical software, and more complicated.

Since I have never programmed a user interface on the Android platform, nor did know whether there are (free) GUI construction tools (there are!), I decided to draw a mockup of the MP3 player app first. The main view of the player ought to look something like this:

Mockup for an MP3 player app.
Mockup for a MP3 player app.

I never prototyped an user interface before, that is why it took me a while to draw the mockup. With hindsight it was not a very clever, productive, or even sensible idea to go for a photo-realistic mockup.
Nonetheless it was educating in many ways. Below you will read about the tools used to draw this mockup.

In my last posting I wrote about tools for drawing mockups, and you might ask yourself «why did he not use one of them instead of going for GIMP and Inkscape?» The simple reason is, that I created the mockup before I tested these tools. And still I would prefer those two over a specialized application because they are standard open source tools and widely available.

GIMP—The GNU Image Manipulation Program

In my first attempt to mock up the MP3 player interface I chose GIMP because I would work mainly with bitmaps. Look at the figure above. It consist of the Android status bar and the application name next to the little robot icon. They are just a portion of a screenshot I took from the Android emulator. To get them I merely created a new Eclipse project on my Fedora desktop named «Music Player». The compact disc is derived from a photo on Wikipedia. The player buttons are part of the official mockup templates provided by Google. The rest—text labels and gradients—can be made with three clicks in GIMP. The smartphone frame never made it into the GIMP mockup, because I ditched GIMP when I was approximately this far:

Not all works as well as bitmap manipulation in GIMP.

The crux with GIMP is rearrangement. GIMP describes images as a set of layers, each layer drawing something on top of the others. Graphical operations, e.g. strokes of a brush, manipulate a layer but are not individual entities that can be changed later. That means, anything you plan to move or change in the future must be in a separate layer. But layers cannot be grouped or easily rearranged (except their stacking). Playfully shifting the interface elements around is out of the question with GIMP. You have to know in advance where every element has its place. Go into a team meeting with a GIMP mockup and be prepared to sweat: «Would it not look better if we swapped the text labels with media controls? Would you please, John?»

Gimp is at its best when preparing the individual bitmap templates of your mockup, e.g. the buttons and images. It is less suited for arranging them into a mockup. And it is a disaster if you need to rearrange things. The freshly released version 2.8 might mend some of these pains.

Inkscape to the rescue

Inkscape is a very powerful open source vector graphic suite. It can do all the things needed to draw a perfect mockup, and much more. The last is not necessarily a blessing. Not without reason are the specialized mockup drawing applications nothing but radically simplified vector drawing suites plus a library of ready-made user interface elements.
That sets the agenda: which are the essential layout functions needed and how are they invoked, and how to compensate for the missing template libraries?

The essential functions for mockup drawing are: placing, moving and re-sizing bitmap or vector objects, plus  stacking, grouping, and arranging them in relation to one another. Placing image objects is pretty obviously done via the menu entry «File > Import…». Next to it is an option to directly import from the Open Clip Art Library. Moving and re-sizing is done by dragging the the object or the arrow handles on its edge with the mouse. Position and size can also be changed by entering coordinates or measures in the top toolbar, which is great for pixel-precise working. Stacking is realized either with layers (from the «Layer» menu) or raising and lowering  individual objects (from the «Object» menu). Multiple object can be selected by holding the SHIFT-key and then be grouped (CTRL-G). Inkscape has powerful alignment functions. The alignment panel can be shown by pressing «SHIFT-CTRL-A». It contains a selection box for controlling to which reference object the objects shall be aligned. Unfortunately the current release 0.48 of Inkscape offers no smart alignment feature similar to all the specialized mockup applications, i.e. it will not generate guide lines to neighboring objects when you drag an object around. Fixed, page-wide guide lines are also a bit hidden. To create them, click on either ruler and drag a new guide line into position.
You will many find excellent tutorials for Inkscape on the internet.

Only a fraction of the many functions Inkscape offers are needed for drawing a  GUI mockup.

The easiest way to imitate the template libraries of a mockup software is to collect all the interface elements you repeatedly need in a separate document. Then copy and paste the desired elements into your active drawing.
There are a few collections of ready-made interface elements on the internet. In fact, Google provides a complete set of controls, icons, color tables, and fonts for Android 4 GUI prototyping. It even contains phone and a tablet outlines. Unfortunately the stencils and are available only in proprietary formats, or as a rather badly composed PNG-bitmap. At least it is possible for Inkscape to import the icon collection, which is in Adobe Illustrator format, but all the icons will be stacked in one spot. It would be nice to have SVG graphics instead. Olof Brickarp converted some of the core icons to SVG. They are nice but do not exactly match the Android Holo look. For prototyping, this hardly matters.

Conclusion

Free and open source all-purpose graphic processing software is well suited for drawing GUI mockups. The lack of free, ready-made, scalable template collections is a big barrier, though. The designer has to either content himself with bitmap graphics, which might be okay unless print publication is required, or hunt and collect the internet, or to draw the templates himself. The last option is not too hard to archive as long as no photo-realistic look is desired.


Thursday, May 10, 2012

Free Android mockup tools for Linux users

There is a wealth of drawing tools available that can be used for mocking up user interfaces. On Stackoverflow you can find a comprehensive collection of tools for prototyping Android and iOS interfaces. There are web-apps and desktop applications on the list, some free, but most are commercial products. SocialCompare has a «Mockup and Wireframing Design Tools comparison» which also includes pricing.
This article takes a glimpse on prototyping applications that are both free to use and work under Linux.

All-purpose tools

In the end almost any drawing tool will do for drawing a mockup, be it a vector drawing tool like the commercial Adobe Freehand or the free and open source Inkscape, be it a classical bitmap drawing application like Adobe Photoshop or the free and open source GIMP, or be it a diagramming software like Microsoft Visio or Omnigroups Omnigraffle; even presentation programs like LibreOffice Impress will do. Browsing a a software directories like alternativeTo will explode this list.

Prototyping with GIMP
Layering is the way to arrange user interface elements with the GIMP.

The catch with these all-purpose application is that their learning curve is quite steep and that they usually lack templates for prototyping. Enter dedicated mockup applications. These tools dispose of every option and function not needed for prototyping, plus provide ready made sets of user interface elements.

From the aforementioned list on the Stackoverflow I only tried standalone application or web applications that a) seemed suitable for Android prototyping, b) appeared to be not too heavy weight in either download size and functionality, c) come free of charge (though maybe crippled), and d) run under Linux. Hence the following text covers only a small fraction of applications available on the market. More can be found at KONIGI, for instance.

Mockingbird

The web application Mockingbird strives for simplicity in every aspect. The functionality is trimmed down to the functions essential for layout: stacking, aligning, and grouping, plus tuning some properties of the interface elements. As you can see in the screenshot below, the interface templates look clear and minimalist. I liked that. There are no platform specific controls available, consequently. Navigation between individual screens can be establish through hyperlinks. Multiple users can share a project.
Mockingbird does not require a Flash player.

It only takes a few minutes to sketch a user interface with applications like Mockingbird.

The one thing I liked best about Mockingbird was the on-the-fly alignment feature. When you drag an object around, Mockingbrid will create guiding lines to all the neighboring elements. I never needed the alignment menu to spread out the controls of my mockup. Quite a few applications (in fact all in this article except Yeblon ) offer such guides, but Mockingbird's implementations works particularly well.

Mockingbird's guiding lines make the alignment menu unnecessary.

Mockingbird is a freemium service. Free users are limited to a single project and one collaborator.

iPlotz

The next contestant, iPlotz, is also freemium web service. Free users are barred from collaborative mockup editing, but are otherwise pretty unrestricted. This makes iPlotz a great choice for solitary developers.
There is a desktop application available for sale. It is implemented in Adobe Air and should run on all major platforms.

The drawing tool of iPlotz offers many professional features.

IPlotz offers much more features than Mockingbird, many of which will appeal to professional designers, for instance page masters, layers, and data sources (tables) that can be connected to various user interface elements. The template library of iPlotz leaves nothing to be desired. It also includes user interface elements for Android and the iPhone, though the style of the Android controls is rather antique. If the template library  does not contain an element needed, the user can compensate by drawing polygon shapes, lines, or importing bitmap graphics. Interface elements can be linked to other pages of the design or the WWW to simulate page flow.

iPlotz also includes project management features.
In addition to mockup drawing, iPlotz offers some project management features. The user can manage multiple projects, add collaborators, and assign task to them.

Yeblon

Yeblon comes free of charge, but is really no more than a toy. Simplicity is one thing, but Yeblon is barren featurewise. The most fundamental flaw being that the text on the very limited set of templates cannot be changed. This forces the user to choose simple text over specific controls. After all, what is the use of having three buttons on a mockup all named «label»?

Yeblon is not suitable for mockup drawing, or anything.

Grouping and aligning of objects is not possible, there are no collaboration features. Every saving of the design yields a publicly accessible URL, which is neat for sharing. The file however is referenced by a sequential number within the URL (mine was only 1968—so much for popularity), which means no privacy. Randomly picking a few layouts other users made, it became pretty clear how the typical Yeblon use-case looks like: try to draw something, fail, leave and never come back. I recommend skipping the first three steps.

MockFlow

MockFlow is the last of the web applications I tested. Just like iPlotz it was made with Adobe Air and a desktop application is available. Free-of-charge usage is possible, but MockFlow places more restrictions on free users than iPlotz. Especially the limitation to only a single project with a maximum of four pages hurts.

MockFlow offers only basic layout function, but the library really shines.

Anyone who tried one of the aforementioned applications will immediately feel at home with the drawing view of MockFlow. It sports a template library on the right from which the user drags the desired user interface elements onto the canvas. Grouping and alignment works as expected. The library is well equipped. Additional components can be added from the «MockStore». It includes a complete set of user interface component of the Android 4.0 Holo theme. It would be even better if one could change the color of the included icons.
I did not try any of the online collaboration features. But for every project a public URL can be created, which is really nice. Unlike Yeblon, the public URL cannot be guessed.

The most severe flaw of MockFlow is its sluggishness. Placing user interface elements was almost impossible. It felt like drawing the object through tar. I tried Firefox and Chromium. Unless this is fixed, MockFlow is no competition for iPlotz or Mockingbird.

Pencil

Finally, with Pencil there is a contestant that is not a web app. It is actually an add-on for the Firefox web-browser, but can be run as a stand-alone application via the xulrunner. On my Fedora 16 desktop this latter way was blocked because the application package was outdated. There are ways around this, but they are cumbersome. Pencil is the only free and open source application on this list.

Again Pencil looks pretty much as all its competitors. Its library contains all the fundamental components for user interface design. Android templates must be imported. Simple generic polygon shapes can be drawn and images imported. The appearance of most components can be adjusted in much detail.

Pencil is a free and open source application build on top of Firefox.

Alignment and re-sizing did not work as smooth as with the competitors. Collection management is rather painful. Page flow can be established by links on any component, though the option to create them only appears when there actually are multiple pages. Pencil implements—not surprisingly—no online collaboration features.

I cannot withhold a final rant, that is not altogether related to Pencil: Implementing any application that is not internet-related as a browser add-on is just sick. It is even worse than the other scourge of humanity discussed here: the web application. The latter is also a perversion (though a useful one) because it abuses the web browser for what it was never meant to be: an operation system; the biggest pimps of this ill fad being Google and as of late Mozilla. Web applications at least may offer some collaboration features and are ready at your fingertips. But what benefits does an implementation as a browser add-on bring? It only makes one of the greediest memory hogs on a desktop system fatter—Firefox that is!

Conclusion

There seems to be a pattern inherent to GUI prototyping applications. If you know one you know them all. If I, as a solitary developer who wants to invest not a single dime, would have to pick from the list above, I probably would go for either iPlotz or Pencil. The former because of its feature richness, its fully equipped library of GUI components, and because it places the fewest restrictions on free riders. Pencil feels not quite as professional as iPlotz, but is has the FLOSS bonus. Third place goes to Mockingbird, which I really liked for its minimalist approach and ease of use. It would rank better would its free plan not be so restrictive. MockFlow could compete with iPlotz if it was not plagued by sluggishness, check it out for yourself, if it works smooth enough for you. Yeblon is really just a toy.

[Changelog]

2012-05-14: Added a link to a comparison of mockup tools at SocialCompare.

Tuesday, May 8, 2012

Developing mobile apps—getting started

During the next couple of weeks I am going to dive into mobile app development. The Android platform will be my starting point for the simple reason that I own an Android phone. My first app will be a simple MP3 player, just like the one that ships with every phone. It is not very ingenious, I admit it, but for the educational purpose it is okay. And actually, there is an itch I need to scratch with the players I have tried so far (and certainly with the default player). But more on this later.

The educational milestones for the immediate future are:

  1. Build working but non-functional user interface for the main view of the music player. This will unveil how difficult it is to build a simple user interface on the platform.
  2. Add basic media player functionality, like starting, stopping, and pausing the playback, skipping tracks, and so on. This will show how to interact with a system service (which media playback hopefully is) and how to perform background tasks.
  3. Add more views for selecting media files by album, artist, and genre. This will introduce some of the more complex user interface controls. Passing to an fro between the different views will be required, and maybe some metadata scavenging also.
  4. Trigger player functionality by gestures, for instance wiping the screen from left to right for skipping to the next title on the play list. This will teach me about gestures, obviously.
  5. Add bells and whistles, meaning: animation. Mobile devices often sport playful user interfaces. Some provide valuable feedback to the user, other are merely showing off. Performing gestures without animation might be awkward, so this milestone might get a promotion.
  6. Turn the player into something useful.

After I made some  progress though this list with the Android app, another OS will join the circus. That should be when I reach milestone 3. The next OS will be either Windows Mobile or Samsung's Bada. The former because phones for that platform are comparatively cheap, the latter because my wife owns a Bada phone. The third OS will be iOS, alas.