The beauty of Custom Views in Android and How to do it!

Douglas Iacovelli
4 min readJan 23, 2018

--

Sometimes in Android you have a certain layout that needs to be used in several places with just minor changes. Sometimes it is just a small set of views and you don't want to implement a RecyclerView due to the boilerplate code or because there are just too few elements to be worth it.

For these specific cases I recommend creating your own CustomView. That's because you will end up saving time if you want to make any changes to this view and so on.

Why can't I just use <include> ?

Because they are meant to include views as they are, which means you can't pass any parameter.

Let's code

You will learn how to inflate a custom layout for your view and pass two different parameters. It's quick and easy!

The code is available on my Github

This is what we are looking for:

Design by Jonny Czar

Basically this can be achieved with a HorizontalScrollView and one CustomView with different images and texts:

First, let's create our custom layout: This will be named benefit_view.xml

Mind that I've created the android:id for both of my components that I want to change the content.

Tip: Use tools:text and tools:src to preview how your views are going to look.

Now we have to create a file inside values called attrs.xml . If you already have one skip the creation.

Now add the <declare-styleable... tags just like that:

  1. It's a good practice to keep the name of the declare-styleable the same as your custom view. In this case I'll call my customView BenefitView
  2. Create the attr tags for the custom parameters you want.
  3. If you want to know other formats you can receive as parameters, please check this answer at StackOverflow

Now we can create our BenefitView.kt

  1. The constructor will receive two arguments, Context and AttributeSet. And It should extend some existing view, for example LinearLayout or RelativeLayout. If you want to adapt the EditText or a Button you can extend those too.
  2. The init tag will be automatically executed after the instantiation of the object in Kotlin
  3. We will get the reference of those elements we gave ids.
  4. We set the variable attributes with the styleable we created in attrs.xml
  5. We set the image and the text values by getting them with this notation: R.styleable.BenefitView_image and R.styleable.BenefitView_text
  6. Don't forget to recycle the attributes, it is necessary for android memory management.

We're almost done. Now we just have to use our CustomViews. If it doesn't appear at first, clean and rebuild the project.

Here's how we're gonna use our BenefitView

It's going to be the namespace of your project until the folder your CustomView is located.

You can still use parameters such as width and height because it extends an Android View.

Mind that to use the custom attributes, you have to add this line to the root layout element:

xmlns:app="http://schemas.android.com/apk/res-auto

And then use this prefix app before the custom attribute. Here's the example of the usage.

Remember: if it doesn't appear at first, clean and rebuild the project.

Code available on my Github

If you like it, please show your support clicking on the clap icon below and share it with your friends :) Thanks!

Update:

Some people left comments on the article claiming that I could have used the merge tag in order to reduce the number of layouts, however I could not use it due to some facts:

The root tag of this custom view has a background drawable and a defined width. I found a way to solve these issues:

  • Background: Set it programmatically on the initialisation of the view: setBackgroundResource(...) and also set the padding programmatically.
  • Width: Set it manually on each usage of the BenefitView

The merge tag is indeed useful but in cases where the parent tag is simpler. In my opinion that is the kind of tradeoff I don't want make. Phones today are not the same as they were before and they're much more capable. Nowadays we have ConstraintLayout, which already helps us to reduce the depth of our layouts, hence I prefer to keep the LinearLayout as the root tag of my custom view if they need some level of customisation :)

I invite you to fork my repo and post on the comments if you find a better way to do it with the merge tag.

--

--

Douglas Iacovelli

Engineering manager who loves building mobile apps and sharing knowledge. If you want to know part of my learnings, follow me :)