Over a million developers have joined DZone.

How To Make a Custom View in Android

DZone 's Guide to

How To Make a Custom View in Android

This tutorial shows you how to create a custom view in your Android app to easily give you more control over the appearance and other properties of your app.

· Mobile Zone ·
Free Resource

Android provides you with a bunch of common views and ways to modify them. Sometimes you need to set a few of the same properties on the same types of views throughout your app. In that case, you could make a layout and use the include tag to include it in every layout you need it in, so you can re-use it wherever you need it.

That may be fine, but what if you want to change a property on that view in one place it’s included? For example, you want to change the text color of a TextView inside that layout. Since it’s in the included layout, you can either change it for every place it’s used or you have to do it programmatically. You can’t set it through the include tag.

To solve this problem, you can create a custom view by extending one of the existing views.


To demonstrate this, I created an example custom view. It extends from LinearLayout and has two TextViews inside of it.

public class CustomView extends LinearLayout {

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.customview, this, true);

        String title;
        String subtitle;
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView, 0, 0);

        try {
            title = a.getString(R.styleable.CustomView_customViewTitle);
            subtitle = a.getString(R.styleable.CustomView_customViewSubtitle);
        } finally {

        // Throw an exception if required attributes are not set
        if (title == null) {
            throw new RuntimeException("No title provided");
        if (subtitle == null) {
            throw new RuntimeException("No subtitle provided");

        init(title, subtitle);

    // Setup views
    private void init(String title, String subtitle) {
        TextView titleView = (TextView) findViewById(R.id.customview_textview_title);
        TextView subtitleView = (TextView) findViewById(R.id.customview_textview_subtitle);


I could have added the TextViews programmatically, but I prefer to have a layout inflated instead. You can see the layout below:


        android:layout_height="wrap_content" />

        android:layout_height="wrap_content" />


I use the merge tag so the layout can be inflated directly into my view, which is a LinearLayout.

In my CustomView layout, I have TextViews for a title and subtitle. I want to be able to set these in any layout where they are included, so I have to add custom attributes in my attrs.xml file.

<?xml version="1.0" encoding="utf-8"?>

    <declare-styleable name="CustomView">
        <attr name="customViewTitle" format="string" />
        <attr name="customViewSubtitle" format="string" />

Now, to actually use this view, I created an example activity which adds my view to its layout.

<?xml version="1.0" encoding="utf-8"?>

        app:customViewTitle="My Title"
        app:customViewSubtitle="My Subtitle"/>

        app:customViewTitle="Other Title"
        app:customViewSubtitle="Other Subtitle"/>


The result looks like this:


I had included checks to make sure the title and subtitle were included, throwing an exception otherwise. If they aren’t included, the renderer will not display the views and shows the appropriate exception. For example, if I forgot to set the subtitle, I would see this exception:


The standard views provided by Android are usually enough to solve most problems. But if they are lacking or you find you’re often duplicating layouts, consider making a custom view. It may save you some time.

android ,mobile ,mobile apps ,app development ,android views

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}