February 4, 2013 - 19 comments

15 quirky Android XML layout parameters to know

After working on Android widgets for the last two years I've learned a lot about limitations, inconsistencies, and ghostly parameters in Android XML layout files. Some parameters are simply "overly clever" so I'll offer some standard settings you should use. These suggestions will also help you effectively reduce the plethora of nanny nag warnings in the IDE.

These come in handy so take a moment to review.

ImageView

This one's a manual fix for "optimized" code in scaleType="fitCenter". Basically when Android adds an image resource to the ImageView it tends to get the width & height from the resource instead of the layout. This can cause layouts to reposition around the full size of the image instead of the actual viewable size.

AdjustViewBounds forces Android to resize the ImageView to match the resized image prior to laying everything else out. There are times where this calculation won't work, such as when the ImageView is set to layout_width="0dip". If it's not working, wrap the ImageView in a RelativeLayout or FrameLayout which handles the 0dip flexible size instead.

TextArea

In the old days, singleLine was pretty straightforward and powerful. But now it's (mostly) deprecated and you should use maxLines="1". Unfortunately, maxLines is weak in comparison. The biggest advantage is that singleLine would ignore carriage returns (\n) and place all text on a single line, sometimes even squeezing text together. MaxLines doesn't bother.

Although singleLine is deprecated, it's still in heavy use in older Android apps on old Android phones so it's not really going away. But it has been long abandoned and tends to break in unexpected ways. Use maxLines whenever you can and singleLine only when you must.

 

Most Android programmers read & write in left to right (LTR) languages so we presume text should be left to right. However Android is growing and being used by many right to left (RTL) languages these days. The good news is that Android auto-formats for RTL users. But in some cases, such as decorative layouts, your text is specifically meant to be LTR.

To be clear, you should NOT use gravity="left" everywhere. For general text areas & forms you should leave the setting alone and let Android figure it out. But if you're doing something decorative, you'll want to think about gravity="left", because otherwise Android will make it RTL for those users.

 

Another quirk in Android layouts is that TextArea gravity can have multiple values separated by a | pipe. In this case, gravity="right|center_vertical" will give you text aligned to then and centered vertically (i.e. between top & bottom).

 

Another useful decorative setting. I just did a new widget pack that follows JellyBean's all caps text style. Initially, I used code to convert strings to upper case, but then I discovered this setting. Since the caps were strictly decorative it was proper to assign caps in the layout XML instead of the code.

 

While there's no way to do kerning in Android, you can at least do line spacing. 1 is the default and the values work as multiples. 0.9 will give you usefully tight vertical spacing. Anything lower and you'll get overlapping text. More than 1 will give you extra space between lines.

 

The plural of ellipsis is "ellipses", but whatever…

Android has a nasty habit of inserting an ellipsis at the end of text when there's limited room. Sometimes it even substitutes an ellipsis for the last letter!

It's probably a good idea to remove this feature by inserting ellipsize="none" into your TextAreas. If you want something readable with a nice fade, use ellipsize="end" instead.

 

When you're using large fonts, you'll end up with a lot of forced padding around them. This setting should remove the extra padding, but it's pretty inconsistent and depends on how well the fonts were designed. I get very different results between Adobe fonts and Google's Roboto fonts.

 

Negative margin values can also be a good workaround for too much text padding.

 

General Layouts

WeightSum and layout_weight are Android's way of doing percent-based layout area. Each layout's weight is added up to complete the weightSum of the area.

The best way to use weightSum and layout_weight is to always use a weightSum of 1 and use decimal percentages 0.0 - 1.0 for the weights. Any other weightSum sizing pattern will simply confuse and annoy other developers down the road.

 

The common setting for stretchable layouts is  layout_width / layout_height set to match_parent. But when you want it to fit around another container, the Android sdk recommends you use 0dip instead of match_parent. I recommend using 0dip so it's easier to differentiate partial layouts from full-size layouts. It also reduces excessive nanny clutter IDE warnings. I also prefer using dip instead of dp so I know it's hack code and not a real size (since I rarely use dip sizes).

There are some very old pieces of the Android sdk that still don't recognize 0dip for auto-sizing so sometimes you'll still need to use match_parent. If you do and if you're splitting the area among more than one resizable container, be sure that they all use match_parent. You can't mix & match 0dip with match_parent.

Layout_weight is the other critical part in making a container fill in the remaining space around another container. The default weight for all containers is 0. Containers with a layout_weight of 0 get placed first, followed by increasing weights until the highest weight gets placed last (in theory). You can assign a layout_weight as low or high as you want, but in practice you should only use 1.

You can also assign two or more containers each to have layout_weight="1" and Android will split the available area between the layouts of the same weight. You don't need to use weightSum if you want them to be spaced equally.

You can also use weight values to prioritize fill area. For example, if you assign one layout as layout_weight="1" and another as layout_weight="2", then the second layout will get half as much area as the first layout. WeightSum will add up the total weights and divide accordingly. Just remember to use 0dip for your size.

That's it for now. Many of these are commonplace but tricky for beginners, and a few don't come up but are good to keep in mind. Hopefully these tips should help keep things clear.

If you have any questions or suggestions, please add them in the comments.

thnx =)

Published by: radley in Android, Android Tips

Comments

Credo Systemz
January 30, 2017 at 11:07 pm

Well said about Android XML layout parameters to know..Android Training

Mateusz
December 9, 2016 at 5:23 am

Thank you for android:includeFontPadding=”false” :)
That solved my problem with stubborn text with ellipsize=”end” that didn’t wanted to center itself vertically. Have a good day!

Aldo
August 28, 2015 at 7:00 am

Thank you for sharing your deep understanding of quirky android jargons, you just saved my hours of experimenting on weird Android attributes.

Leo
July 31, 2015 at 3:33 pm

Thanks

Emily
December 4, 2014 at 5:16 pm

Thank you so much for the negative dp idea I was trying so hard to get rid of a space

Daniel
July 15, 2014 at 9:43 am

keepScreenOn is also not much known.

Bengalore
April 18, 2014 at 12:27 pm

Thanks a big bunch mate. Your | android:adjustViewBounds=”true” | works like a charm including when applied to an image within a (deprecated) Gallery widget :-).

Karl
March 19, 2014 at 9:47 pm

The plural of ellipse might be ellipses, but that is unrelated to the attribute that decides whether to ellipsize (verb) the text.

    radley
    March 30, 2014 at 11:20 am

    Ellipsize is not a verb, it’s not even a real word.

      Alan
      June 24, 2014 at 5:15 pm

      Ellipsize is a neologism (a made up word). But it is definitely a verb. I suppose because it is not found in a dictionary, the author assumed (incorrectly) that it was intended to be the plural of the noun ellipsis. But no, it is a verbification (see, I can make up words, too!) of the noun ellipsis.

        Random Teenager
        February 19, 2015 at 2:59 pm

        I think maybe they were trying to go with “ellip-size”, if they used “ellipsis” or “ellipses” it might be a it confusing as to what the parameter does.

        I think when they created the parameter it was supposed to be a merge of “ellipse” and “size”, hence “ellipsize” – the parameter is not relative to size, but can actually be associated with a parameter that affects “size” of the ellipses. Such as having none, etc…

        It is probably verbification, but I’m just bringing forward another idea.

Vladimir
March 18, 2014 at 5:26 pm

One more attribute: android:clipToPadding. Very useful with ListView

George
February 17, 2013 at 4:41 am

FYI textAllCaps is only present on API level 14+. So it won’t work on older Android versions.

    TWiStErRob
    August 14, 2015 at 5:24 am

    That’s actually a good thing, because the unknown params are ignored on lower API levels. Radley said “follows JellyBean’s all caps text style” so if you’re using that you can be sure it doesn’t contradict an older Android’s design. The problem is if you want to have an all-round-same design you have to write code to convert to all caps for compatibility.

Thomas
February 5, 2013 at 12:35 pm

Another nastiness is lineSpacingMultiplier – as you said, values below 1.0 may give you overlapping in some fonts. What they almost every time give you however are cropped last lines, because the sdkis unable to determine the correct height of such a multi line text view.

    radley
    February 5, 2013 at 12:44 pm

    I think you can extra padding on the bottom to compensate.

      Thomas
      February 5, 2013 at 4:32 pm

      No, that was not working for me. The only way to “fix” this problem was to create my own TextView implementation and let this overwrite onMeasure(). I calculated some “magic height value” that I set as new measured dimensions, which then expanded the text’s box accordingly.

Daniel
February 5, 2013 at 7:43 am

You missed one of my most often used quirky XML attributes – ScrollView’s fillViewport. Romain Guy explains it pretty well here: http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/

Leave a Reply