Android layout tricks #3: optimize by merging (Android layout Tips 3: Use merge optimization)

Source: Internet
Author: User
03 March 2009

Android layout tricks #3: optimize by merging

In the previous installmentAndroid layout tricks, I showed you
How to Use<include />Tag in XML layout to reuse and share your layout code. I also mentioned
<merge />And it's now time to learn how to use it.

The<merge />Was created for the purpose of optimizing Android layouts by grouping the number of levels in view trees. it's easier to understand the problem this tag solves by looking at an example. the following XML layout declares a layout
That shows an image with its title on top of it. The structure is fairly simple;

Framelayout is used to stack
Textview on top of
Imageview:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <ImageView          android:layout_width="fill_parent"         android:layout_height="fill_parent"             android:scaleType="center"        android:src="@drawable/golden_gate" />        <TextView        android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_marginBottom="20dip"        android:layout_gravity="center_horizontal|bottom"        android:padding="12dip"                android:background="#AA000000"        android:textColor="#ffffffff"                android:text="Golden Gate" /></FrameLayout>

This layout renders nicely as we expected and nothing seems wrong with this layout:

Things get more interesting when you inspect the result
Hierarchyviewer. If you look closely at the resulting tree you will notice that
FrameLayoutDefined in our XML file (highlighted in blue below) is the sole child of another
FrameLayout:

Since ourFrameLayoutHas the same dimension as its parent, by the same ue of using
fill_parentConstraints, and does not define any background, extra padding or a gravity, it is
Totally useless. We only made the UI more complex for no good reason. But how coshould we get rid of this
FrameLayout? After all, XML documents require a root tag and tags in XML layouts always represent view instances.

That's where<merge />Tag comes in handy. When
Layoutinflater encounters this tag, it skips it and adds<merge />Children to
<merge />Parent. Confused? Let's rewrite our previous XML layout by replacing
FrameLayoutWith<merge />:

<merge xmlns:android="http://schemas.android.com/apk/res/android">    <ImageView          android:layout_width="fill_parent"         android:layout_height="fill_parent"             android:scaleType="center"        android:src="@drawable/golden_gate" />        <TextView        android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_marginBottom="20dip"        android:layout_gravity="center_horizontal|bottom"        android:padding="12dip"                android:background="#AA000000"        android:textColor="#ffffffff"                android:text="Golden Gate" /></merge>

With this new version, bothTextViewAndImageViewWill be added directly to the top-level
FrameLayout. The result will be encoded ally the same but the view hierarchy is simpler:

Obviusly, using<merge />Works in this case because the parent of an activity's content view is always
FrameLayout. You cocould not apply this trick if your layout was using
LinearLayoutAs its root tag for instance.<merge />Can be useful in other situations though. For instance, it works perfectly when combined with
<include />Tag. You can also use<merge />When you create a custom composite view. Let's see how we can use this tag to create a new view called
OkCancelBarWhich simply shows two buttons with customizable labels. You can also
Download the complete source code of this example. Here is the XML used to display this custom view on top of an image:

<merge    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:okCancelBar="http://schemas.android.com/apk/res/com.example.android.merge">    <ImageView          android:layout_width="fill_parent"         android:layout_height="fill_parent"             android:scaleType="center"        android:src="@drawable/golden_gate" />        <com.example.android.merge.OkCancelBar        android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:layout_gravity="bottom"        android:paddingTop="8dip"        android:gravity="center_horizontal"                android:background="#AA000000"                okCancelBar:okLabel="Save"        okCancelBar:cancelLabel="Don't save" /></merge>

This new layout produces the following result on a device:

The source codeOkCancelBarIs very simple because the two buttons are defined in an external XML file, loaded using
LayoutInflate. As you can see in the following snippet, the XML Layout
R.layout.okcancelbarIs inflated withOkCancelBarAs the parent:

public class OkCancelBar extends LinearLayout {    public OkCancelBar(Context context, AttributeSet attrs) {        super(context, attrs);        setOrientation(HORIZONTAL);        setGravity(Gravity.CENTER);        setWeightSum(1.0f);                LayoutInflater.from(context).inflate(R.layout.okcancelbar, this, true);                TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 0, 0);                String text = array.getString(R.styleable.OkCancelBar_okLabel);        if (text == null) text = "Ok";        ((Button) findViewById(R.id.okcancelbar_ok)).setText(text);                text = array.getString(R.styleable.OkCancelBar_cancelLabel);        if (text == null) text = "Cancel";        ((Button) findViewById(R.id.okcancelbar_cancel)).setText(text);                array.recycle();    }}

The two buttons are defined in the following XML layout. As you can see, we use
<merge />Tag to add the two buttons directly toOkCancelBar. Each button is removed ded from the same external XML layout file to make them easier to maintain; we simply override their ID:

<merge xmlns:android="http://schemas.android.com/apk/res/android">    <include        layout="@layout/okcancelbar_button"        android:id="@+id/okcancelbar_ok" />            <include        layout="@layout/okcancelbar_button"        android:id="@+id/okcancelbar_cancel" /></merge>

We have created a flexible and easy to maintain custom view that generates an efficient view hierarchy:

The<merge />Tag is extremely useful and can do wonders in your code. However, it suffers from a couple of limitation:

  • <merge />Can only be used as the root tag of an XML Layout
  • When inflating a layout starting with<merge />, YouMustSpecify a parent
    ViewGroupAnd you must setattachToRootTotrue(See the documentation of

    Inflate () method)

In the next installmentAndroid layout tricksYou will learn about
ViewStub, A powerful variation<include />That can help you further optimize your layouts without sacririicing features.

Download the complete source code of this example.

Posted byromain guyat8: 00
AMLabels: How-to, optimization, user
Interface

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.