Home > Tutorials > Create and use a Compound Control

Create and use a Compound Control


What is Compound Control?

Basically, it is a widget/control that containing a group of other controls, something like: an ImageView and a TextView can be used as one instead of two separate controls….

Today, I will guide you on creating a Compound Control like below (one part in my next release Android Application)

Compound Control: HeroInfo Control

Compound Control: HeroInfo Control

I named it HeroInfoControl. As you see on the screenshot, there are three same compound controls I created.

Each HeroInfoControl will display information of one hero in DotA :D, my favorite game!

A – Design the layout

The control contains:

+ a hero icon on the very left of the layout, I define all image displayed here with size 48×48 in pixels.

+ on the top right is also one image that displays hero title

+ on the bottom right is a text which displays hero name.

Generally, a parent ViewGroup appropriate for this one is LinearLayout and a sub LinearLayout to contain the part on the right.

There should a space between the left and the right of the main layout, so a marginRight needs to defined, I guess “5-10dip” is good enough.

The hero name needs to be bold somehow.

The hero name and hero title somehow need to be padded on top and bottom to make it a little center horizontal aligning to the hero icon. It looks a bit nicer then.

That’s all I have for sketching the layout, let’s define it into XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content">

	<ImageView
		android:id="@+id/ivIcon"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:scaleType="fitCenter"
		android:layout_marginRight="5dip"
	/>

	<LinearLayout
		android:orientation="vertical"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"
	>

		<ImageView
			android:id="@+id/ivTitle"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content"
			android:scaleType="fitStart"
			android:paddingTop="5dip"
			android:paddingLeft="10dip"
		/>

		<TextView
			android:id="@+id/tvName"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content"
			android:layout_weight="1"
			android:gravity="left|bottom"
			android:paddingBottom="5dip"
			android:paddingLeft="10dip"
			android:textStyle="bold"
			android:textSize="15sp"
		/>

	</LinearLayout>

</LinearLayout>

B – Code for Layout

The next part is to define the layout and create the real control to use.

Since the parent layout used is LinearLayout, I will extend my compound control to LinearLayout class.

package pete.android.study;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class HeroInfoControl extends LinearLayout {

	private ImageView mHeroIcon;
	private ImageView mHeroTitle;
	private TextView mHeroName;

	public HeroInfoControl(Context context) {
		super(context);

		loadViews();
	}

	public HeroInfoControl(Context context, AttributeSet attrs) {
		super(context, attrs);

		LayoutInflater inflater = LayoutInflater.from(context);
		inflater.inflate(R.layout.hero_info, this);

		loadViews();
	}

	private void loadViews() {
		mHeroIcon = (ImageView)findViewById(R.id.ivIcon);
		mHeroTitle = (ImageView)findViewById(R.id.ivTitle);
		mHeroName = (TextView)findViewById(R.id.tvName);
	}

	public void setHeroIcon(Drawable icon) {
		mHeroIcon.setImageDrawable(icon);
	}

	public void setHeroTitle(Drawable title) {
		mHeroTitle.setImageDrawable(title);
	}

	public void setHeroName(String name) {
		mHeroName.setText("::" + name + "::");
	}

}

You need the constructor with AttributeSet in order to use it in XML layout. Well, it’s quite simple, I guess no need to explain the above code.

So, we’ve done creating our control, it’s time to use it!

C – Use the Control

As sample, I will put three controls in layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

	<pete.android.study.HeroInfoControl
		android:id="@+id/heroLuna"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_marginTop="5dip"
		android:layout_marginBottom="5dip"
	>
	</pete.android.study.HeroInfoControl>

	<pete.android.study.HeroInfoControl
		android:id="@+id/heroTiny"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_marginTop="5dip"
		android:layout_marginBottom="5dip"
	>
	</pete.android.study.HeroInfoControl>

	<pete.android.study.HeroInfoControl
		android:id="@+id/heroKael"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_marginTop="5dip"
		android:layout_marginBottom="5dip"
	>
	</pete.android.study.HeroInfoControl>

</LinearLayout>

You probably need to put all images into resources folder.

Remember to use your control with fully qualified tag like above, otherwise, it won’t work.

Make code and set their values:

package pete.android.study;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    HeroInfoControl heroLuna;
    HeroInfoControl heroTiny;
    HeroInfoControl heroKael;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        heroLuna = (HeroInfoControl)findViewById(R.id.heroLuna);
        heroLuna.setHeroIcon(getResources().getDrawable(R.drawable.luna));
        heroLuna.setHeroTitle(getResources().getDrawable(R.drawable.luna_title));
        heroLuna.setHeroName("Luna Moonfang");

        heroTiny = (HeroInfoControl)findViewById(R.id.heroTiny);
        heroTiny.setHeroIcon(getResources().getDrawable(R.drawable.tiny));
        heroTiny.setHeroTitle(getResources().getDrawable(R.drawable.tiny_title));
        heroTiny.setHeroName("Tiny");

        heroKael = (HeroInfoControl)findViewById(R.id.heroKael);
        heroKael.setHeroIcon(getResources().getDrawable(R.drawable.kael));
        heroKael.setHeroTitle(getResources().getDrawable(R.drawable.kael_title));
        heroKael.setHeroName("Kael");
    }
}

There you go, your compound control is done with the sample.
You can make any kind of control you want :)
Hope you like it!

Cheers,
Pete Houston

About these ads
  1. Rico
    December 4, 2013 at 4:02 am | #1

    Where do you put and load the layout informations, when you want to create each item dynamically at runtime?

  2. Mohammed Raes
    August 23, 2012 at 7:59 pm | #2

    After creating the compound control, is it possible to use this control directly from palette like a button or edit text .widget .

    • Droid Dev
      December 4, 2012 at 8:41 pm | #3

      I was wondering the same thing. And is it possible to design the new compound component with a WYSIWYG tool such as the one ADT has for designing layouts?

  3. vivek
    January 5, 2012 at 1:01 am | #4

    Thanks a lot , helped me a lot

  4. November 10, 2011 at 8:41 am | #5

    dude, everytime I try to run the code I get a nullpointerException when I try to assign a value from R.drawable

  5. Dan
    October 20, 2011 at 8:49 am | #6

    Great explanation. Thanks for writing this.

  6. July 9, 2011 at 7:21 pm | #7

    The standard for all heroes defined here: http://playdota.com/heroes

  7. trungh0
    July 9, 2011 at 6:56 pm | #8

    What do you do if a hero have alot of name?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: