Advertisements

Diagnosing Layout Problems

Tips & Tools Diagnosing Layout Problems

Yesterday, a post came over the transom on the [android-developers] Google Group, citing a problem in getting a RelativeLayout to work properly as a row in a ListView. Since I screwed up my initial response to that post, I figured I’d document and write up a blow-by-blow account of the diagnostic steps I went through to in order to determine what is going wrong.

To give you a clue as to the final outcome, the subtitle of this post should be “How I Learned to Stop Worrying And Love the Box Model”…

First, here is his original row layout (with only some reformatting applied):

[sourcecode lang=”xml”]





[/sourcecode]

I put together my own test scaffold activity to use this row:

[sourcecode lang=”java”]
public class DiagnosticDemo extends ListActivity {
String[] items={“lorem”, “ipsum”, “dolor”};
static int ROW_TO_TEST=R.layout.row_original;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setListAdapter(new TestAdapter(this));
}

class TestAdapter extends ArrayAdapter {
Activity context;

TestAdapter(Activity context) {
super(context, ROW_TO_TEST, items);

this.context=context;
}

public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View row=inflater.inflate(ROW_TO_TEST, null);

return(row);
}
}
}
[/sourcecode]

That gave me the following visual result:

The original layout that needs fixing

Since that seemed to line up with what the author was getting, I felt I had reproduced the problem, and set about getting it to work. This eventually took 13 different test layouts. Since this post would be a mile long if I documented each and every one of them, I’ll pick out the highlights.

First, I added background colors, so we could better see what widget is taking up what space on-screen:

[sourcecode lang=”xml”]





[/sourcecode]

The same layout, with ugly colors

While ugly, the colors do help to demonstrate what is what. The RelativeLayout is brick red, the LinearLayout is blue (of which only a hint can be seen), and the three TextViews are green, mustard yellow,… and the third is not visible in the layout.

Eventually, I tried switching to a full box model, trying to figure out why the two stacked TextView widgets were appearing on top of each other:

[sourcecode lang=”xml”]


[/sourcecode]

Switched top-level layout to be LinearLayout

Now, we see the first TextView (“Upper”) in purple and no lower one.

Thinking that the problem might be one of layout weights, I added android:layout_weight=”1″ to each of the stacked TextView widgets, which got me:

After adding layout_weight to the stacked TextViews

You see that they are now somewhat stacking, but their full height is not being properly utilized, so they are somewhat squashed.

On a whim, I commented out the “Left Center” TextView, and got:

After removing the Left Center TextView

So now they’re stacking. This suggests that, somehow, the height of the layout was being dictated by the initial TextView more than the stacked pair of TextView widgets.

I then started trying to work this back into a RelativeLayout overall parent, yielding:

[sourcecode lang=”xml”]





[/sourcecode]

After returning to a RelativeLayout and layout_centerHorizontal=true

Note the use of layout_centerHorizontal="true" rather than layout_centerInParent="true". One would think they should be equivalent in a row whose height is being dictated by the to-be-centered widget. In practice, it appears layout_centerHorizontal works better in this case. Needless to say, we now have our stacked TextView widgets properly positioned.

So, we uncomment our “Left Center” TextView and…

After restoring the Left Center TextView

On the plus side, it did not foul up our Upper and Lower TextView widgets. On the other hand, the Left Center TextView is still misbehaving.

If we change the Left Center TextView to use layout_alignParentBottom="true" instead of layout_centerVertical="true", we see:

After setting the Left Center TextView to align with the parent\'s bottom

That should have the Left Center TextView‘s bottom aligned with the parent’s bottom. Combine this with the previous result, and it would appear that the RelativeLayout knows the proper height, but for some reason is translating the position upwards by 50%, which is fouling up the layout.

And at this point, I surrendered. This could be a bug. This could be the ways of RelativeLayout being inscrutable.

If this were my application, I’d dump the RelativeLayout and stick to a “box model”, using nested LinearLayouts:

[sourcecode lang=”xml”]


[/sourcecode]

Dumping the whole thing and rebuilding it via LinearLayout

Technically, this is not the same as the original. In the original, the author wanted the Upper/Lower TextView pair to be centered across the row. In this implementation, they are centered across the part of the row not used by the Left Center TextView. The difference is subtle to the naked eye, and it may be the replacement will suffice for the application’s business needs.

Guest Blogger
Posts published under this byline have paid for sponsored placement on this website. AndroidGuys does not claim any responsibility for it beyond the pre-approved links and content.