Tuesday 25 October 2011

Android Annoyances: Text Length

It is incomprehensible to me why there are properties that you can set in an XML attribute but not in code. Here is one quite obvious example.

I have an EditText control for text input and I want to limit the length of input to just two characters. No problem, I can do that easily in XML layout:

android:maxLength="2"

The problem is: in some circumstances I want to limit input to only 1 character, and can only do that in code. Surely enough, if there is such an XML attribute, there should be a setMaxLength() method, right? Wrong. The guys who designed Android API just didn’t think it might be needed.

Rubbish.

Saturday 22 October 2011

Quartz 2D Article

When developing for iOS, a few times I was working on a bespoke graph, either copying a design created by someone else or implementing strict design guidelines. I decided to share the experience I've gained then in a series of articles. Here they are:

Part 1. Preparing the environment, drawing the grid lines.
Part 2. Drawing a bar graph, with gradient fill.
Part 3. Drawing a line graph, with gradient fill.
Part 4. Making graphs interactive.
Part 5. (to be published soon) Drawing text on graphs (labels etc).

Sunday 9 October 2011

GWT, GXT and Compilation Problem

I found an excellent book that finally explained me the differences between a number of extensions to Google Web Toolkit, and served as an excellent introduction into Ext GWT, a.k.a. GXT.

I started playing with the framework, and it is powerful and beautiful. It seemed to be quite sluggish when developing locally, but when deployed to the server it works much better, I don’t see any problems with performance.

However, my first attempt to deploy my project to the AppEngine wasn’t successful, I’ve got a rather esoteric error message:

java.lang.IncompatibleClassChangeError: Found interface com.google.gwt.core.ext.typeinfo.JClassType, but class was expected

Fortunately, there is already a raised issue for this. It looks like after GWT reached version 2.2, a number of other solutions became incompatible with it, and that seems to be the case with GXT as well.

The solution was to downgrade GWT to version 2.1. Then I had to replace this line of code in the project’s module:

<inherits name='com.google.gwt.user.theme.clean.Clean'/>

with this one:

<inherits name='com.google.gwt.user.theme.standard.Standard'/>

After this, the project has deployed successfully. However, today I tried to run it locally, and GWT plugin in the browser can’t connect to the local server. I guess the reason is that I downgraded the GWT itself but haven’t downgraded the plugin. A bit of a mess.

I’ll need to tell the GXT folks about this problem when I have more time.

Friday 7 October 2011

Android Annoyances: Layout Rules

Quite often, working with Android, I have a strong feeling that a method is missing that actually should exist in the API. Say, there can be a getter but no setter. In some cases, I understand that the property I am trying to change is read-only, but in the other cases there is an impression that someone who was designing the API just didn’t spend enough time thinking on it.

Here is one of the recent stories.

Android doesn’t give us many opportunities for controlling the positioning of views and controls. This is understandable: taking into account the wide array of screen sizes and densities, we’d better trust the automatic layout and pray that it does something good for us. However, we can still achieve quite a lot by manipulating layout parameters, and RelativeLayout is probably the most helpful in this respect.

RelativeLayout.LayoutParams method offers us a couple of useful methods:

addRule(int verb)
addRule(int verb, int anchor)

Using them, we can dynamically, in the code, put a view on top of another view, or align it, say, to parent bottom.

Great, so we can add a rule that we need. Surely, there should be a possibility to remove the rule that we don’t need anymore, right? Say, we’ve aligned a view to parent bottom first, but then we want to place it above another view. We might try to do it like this:

params.addRule(RelativeLayout.ABOVE, R.id.someview);

But this won’t work: the view will stay aligned to the parent bottom. There should be a method to remove a rule that was added - but go try to find it in the API. It doesn’t exist.

Quite typically, Android still leaves us a possibility to achieve what we want but at the price of writing some ugly code - and spending time to discover that ugly solution. Here is how I managed to remove the rule that I don’t need anymore:

params.getRules()[RelativeLayout.ALIGN_PARENT_BOTTOM] = 0;

If you know a better way, please let me know.