Skip to main content

Command Palette

Search for a command to run...

The merge tag, my custom view savior (Improve your custom layout performance on Android)

Updated
3 min read
The merge tag, my custom view savior (Improve your custom layout performance on Android)

So, recently I was working on something similar to a “create account” screen, basically a staple of most android apps. The design demanded that the input fields on this screen have a lot of custom behavior and a different look from the default EditText appearance on Android. So my first idea was to make a custom view(layout) for my input field, since this would save me from a lot of code duplication and generally make things cleaner.

So, I set up the custom view/layout like so:

Nothing out of the ordinary, right?

Now the “create account” screen(or fragment, I use them interchangeably), needed to have about 10 or 11 of these input fields. I lay them out in a Constraint layout like so:

Then I run the app and notice that it takes about 1.5 seconds to load and display this screen (but why? I ask myself). I also notice that anytime I clicked on the input field and then dismissed the keyboard, it left an ugly blank space where the keyboard used to be before, and it took about a second for the layout to resize and display properly(Now, this I could not forgive).

So after searching for answers everywhere, a kind man on a discord forum was nice enough to point out that I was nesting(layering) 3 layers of ConstraintLayouts, where one of the layers was really just a wrapper and not needed, and this was possibly what was wrecking my UI performance.

The unnecessary layer in question was the ConstraintLayout in line 7 of layout_input_field.xml above.

layout_input_field with superfluous ConstraintLayout

That layout here is just a wrapper, and I don’t need it, because I’m creating an InputField(which extends ConstraintLayout) in the create account fragment XML. And inside this InputField class ‘init’ block on line 17, I’m inflating my custom input field XML whose root is a ConstraintLayout and attaching it to its parent which is “this”(the InputField object).

InputField.kt init block

The above statement becomes clear when we look at the parameter list of DataBindingUtil.inflate()

Parameter list of DataBindingUtil.inflate()

But, how do we fix this?

So here comes the tag to the rescue.

What is the merge tag?

To quote the android documentation:

The <merge /> tag is a tag used to help eliminate redundant view groups in your view hierarchy when including one layout within another. For example, if your main layout is a vertical [LinearLayout](https://developer.android.com/reference/android/widget/LinearLayout) in which two consecutive views can be re-used in multiple layouts, then the re-usable layout in which you place the two views requires its own root view. However, using another [LinearLayout](https://developer.android.com/reference/android/widget/LinearLayout) as the root for the re-usable layout would result in a vertical [LinearLayout](https://developer.android.com/reference/android/widget/LinearLayout) inside a vertical [LinearLayout](https://developer.android.com/reference/android/widget/LinearLayout). The nested [LinearLayout](https://developer.android.com/reference/android/widget/LinearLayout) serves no real purpose other than to slow down your UI performance.

So, to use it, I swapped out the ConstraintLayout for the merge tag, like so:

Don’t forget to include tools:parentTag in your merge tag, this helps you retain the design preview that you would have with the parent layout, you inflate into.

Doing something as simple as this, reduced the fragment load and display time by more than 50%, it also eliminated the keyboard ugly blank space issue, because the layout could resize faster.

The End

Can’t believe I’ve spent this much time writing about an XML tag 😂. But sometimes little things can make a big difference, as this did for me, and I’m usually only motivated to write about stuff I figure out after going through a fair bit of trouble to find or fix. Which would explain why it took me over a year to write my second article(that and procrastination). Anyway, it's good to be back.