Skip to content
This repository has been archived by the owner on Feb 26, 2023. It is now read-only.

Enhance custom views

Csaba Kozák edited this page Apr 17, 2015 · 7 revisions

@EView and @EViewGroup are the annotations to use if you want to create custom components.

Why should I use custom components ?

If you notice that you're duplicating some parts of your layouts in different locations in your app, and that you're duplicating and calling the same methods again and again to control these parts, then a custom component can probably make your life a lot easier !

Custom Views with @EView

Since AndroidAnnotations 2.4

Just create a new class that extends View, and annotate it with @EView. You can than start using annotations in this view:

@EView
public class CustomButton extends Button {

        @App
        MyApplication application;

        @StringRes
        String someStringResource;

	public CustomButton(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
}

You can then start using it in your layouts (don't forget the _):

<?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="match_parent"
    android:orientation="vertical" >

    <com.androidannotations.view.CustomButton_
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <!-- ... -->

</LinearLayout>

You can also create it programmatically:

CustomButton button = CustomButton_.build(context);

Custom ViewGroups with @EViewGroup

Since AndroidAnnotations 2.2

How to create it ?

First of all, let's create a layout XML file for this component.

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >

    <ImageView
        android:id="@+id/image"
        android:layout_alignParentRight="true"
        android:layout_alignBottom="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/check" />

    <TextView
        android:id="@+id/title"
        android:layout_toLeftOf="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/white"
        android:textSize="12pt" />

    <TextView
        android:id="@+id/subtitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title"
        android:textColor="#FFdedede"
        android:textSize="10pt" />

</merge>

Did you know about the merge tag ? When this layout will get inflated, the childrens will be added directly to the parent, you'll save a level in the view hierarchy.

As you can see I used some RelativeLayout specific layout attributes (layout_alignParentRight, layout_alignBottom, layout_toLeftOf, etc...), it's because I'm assuming my layout will be inflated in a RelativeLayout. And that's indeed what I'll do !

@EViewGroup(R.layout.title_with_subtitle)
public class TitleWithSubtitle extends RelativeLayout {

	@ViewById
	protected TextView title, subtitle;

	public TitleWithSubtitle(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public void setTexts(String titleText, String subTitleText) {
		title.setText(titleText);
		subtitle.setText(subTitleText);
	}

}

There you are ! Easy, isn't it ?

Now let's see how to use this brand new component.

How to use it ?

A custom component can be declared and placed in a layout just as any other View:

<?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="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <com.androidannotations.viewgroup.TitleWithSubtitle_
        android:id="@+id/firstTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
    <com.androidannotations.viewgroup.TitleWithSubtitle_
        android:id="@+id/secondTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
    <com.androidannotations.viewgroup.TitleWithSubtitle_
        android:id="@+id/thirdTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

As always, don't forget the _ at the end of the component name!

And because I'm using AA, I can just as easily get my custom components injected in my activity and use them!

@EActivity(R.layout.main)
public class Main extends Activity {

	@ViewById
	protected TitleWithSubtitle firstTitle, secondTitle, thirdTitle;

	@AfterViews
	protected void init() {
		
		firstTitle.setTexts("decouple your code",
				"Hide the component logic from the code using it.");
		
		secondTitle.setTexts("write once, reuse anywhere",
				"Declare you component in multiple " +
				"places, just as easily as you " +
				"would put a single basic View.");
		
		thirdTitle.setTexts("Let's get stated!",
				"Let's see how AndroidAnnotations can make it easier!");
	}

}

Most AA annotations are available in an @EViewGroup, give it a try !

Using AndroidAnnotations

Questions?

Enjoying AndroidAnnotations

Improving AndroidAnnotations

Extending AndroidAnnotations

Clone this wiki locally