As a follow-up to this question, I can\'t think of any good reason why I shouldn\'t wrap every included XML layout in a
pair.
Which then lea
The main purpose of the include
tag(the way I see it) is to allow the developer to create reusable xml components to be used multiple times in the same activity or/and across many activities in an app. In order for that reusable component to be really useful it needs to be self contained and with a minimum of outside connections as posible. From my point of view, if you were to use the merge
tag in each included layout this will reduce the usefulness of the include
tag overall. Here is an example why I think this will happen:
Consider that you want to implement a reusable ActionBar
xml component to embed in each of your activities. It will contain a TextView
and a Button
placed horizontally. A layout to do this would be:
R.layout.actionbar
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/actionbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/actionbar_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Now suppose you have two activities in your app, one where the root view is a LinearLayout
(orientation vertical) and one where the root view is a RelativeLayout
. The layout above could easily be included in the LinearLayout
(just put it where you want), the same will be possible with the RelativeLayout
, of course taking in consideration the current elements from that RelativeLayout
(keep in mind that you must set the layout_width/height
(for example, replicated from the included layout's root) for the include
tag in order for the other layout_*
attributes to be considered).
Now take in consideration your proposal. The layout will become:
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="@+id/actionbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/actionbar_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</merge>
Looking at our ActionBar
layout doesn't tell us that much, you just have a TextView
and a Button
to be included somewhere. Now consider the activity where the root is the vertical orientated LinearLayout
. The layout R.layout.actionbar
can't be simply included as this will break our ActionBar
, we need to add an extra LinearLayout
(with orientation horizontal) for our layout to make it look as desired. As you can see you are in the situation above(layout without the merge
tag), but now you have to remember to wrap the included layout in a LinearLayout
with orientation horizontal where ever the parent root is a LinearLayout
with orientation vertical.
Things get even worse when the root is a RelativeLayout
, you can't simply use the include
tag with merge
in a RelativeLayout
(a nice question to read How to get RelativeLayout working with merge and include?). The option is, again, to embed the include
in a LinearLayout
which puts you in the situation without the merge
tag(but now adding more problems than solving). Also reading the last part from this link http://code.google.com/p/android/issues/detail?id=2863 may reveal other bugs with the include
tag.
As you can see from my example above, having the merge
tag by default could result in some problems in certain situation. Also the current system represents a more consistent way to work with layouts(you would create the layout for the include
tag like you create normal layouts with a root View
). Also, the merge
tag is an optimization and I don't think you should try to optimize until you start to see some performance issues(or you really want to squeeze every last drop of performance, at the cost of complexity). The majority of apps will be just fine with the current system, a three-four level deep layout with a decent amount of views could live without the merge
optimization with no problems at all.
Another problem with the merge
tags is that a inflated layout that has merge
as its root is required to attach itself to a parent when inflated. If you were to inflate the R.layout.actionbar
layout then you would have to attach it to a parent:
View actionBar = getLayoutInflater().inflate(R.layout.actionbar, root, true);
I don't know if this is a real limitation, maybe in some rare situation it could be a deal breaker.
Just my opinion about the include
- merge
pair use.