Let’s say you are making a project that has a certain set of views that are often repeated. For example, maybe you are placing a name and address combo in many locations in your project. Currently, if just using the stock views within Android, you may end up repeating the same set of views in your XML files to account for this – a textview for name, a textview for street address, a text view for city etc. What if, instead, you wanted to simply enter a view for address info and then provide it with the information and it automatically creates and fills in all of the pieces? This is a perfect example where custom views can help keep your project D.R.Y.
What are Custom Views?
A custom view is a view that you design in any way you want by extending another view and then overwriting everything you feel necessary. This custom view can then be used in code, and everything defined in it will be inserted wherever it is used. Maybe a stock dialog isn’t the layout you want for all the dialogs in your project? Create a custom dialog you can then call instead.
Let’s walk through the steps of creating a custom view with an example. I am going to create a custom view that contains a user info. This view could then be used anywhere I want to display my user. In my example, the info I need to display includes a username, user level and a logo.
Step 1: Decide what to extend
You can extend from any view/layout, but think of picking a view that provides some functionality you may want [1]. For example, if you are going to want a card, extend card to start and then customize the corners, elevation, content etc so you don’t have to start from scratch. For my example, I am going to extend a linear layout to hold my stuff, as that functionality is all the functionality I need from my parent class.
Step 2: Create layout file
In your layout file, you specify all the details just like you would if you weren’t going to have a custom view. The benefit to this custom view is that now this will only be in this one place instead of repeated everywhere you want to use it. Here is my very simple example layout file:

Step 3: Create a child class extending some view
In my case, I will create the UserInfoView class and extend linear layout.

Within this class I have basically inflated my custom view’s XML file, and then set up the ability to set the imageview’s image and textviews’ texts in both code or via custom XML attributes. Let’s talk about both of these:
Step 4a: Create Custom attributes
To create custom attributes, we declare a styleable (customarily this would live in a res/values/attrs.xml). Place each attribute name in here and then declare what type you are passing in. For example, the username will be a string and the logoRef will be a reference to a drawable.

Next, look in the above picture of my UserInfoView class and note the init function. To access these attributes in our class, we obtain the styled attributes [2]. If attributes are not null, then we can get text and resource by referencing the given name from the styleable and assigning those to wherever we are going to use them in our custom view. One last note, when done with your styled attribute access, remember to call .recycle()
Step 4b: Create variables to dynamically update view in code
The UserInfoView class shows three variables that can be used to dynamically set data for the custom view: username, logo, and level. Custom setters were set up so that when somebody assigns a value to these variables that the resulting textviews and imageview will be updated accordingly.
Step 5: Add custom view to our project
To add this custom view, we can simply use it like any other view in our resource file. In this example program, we use it twice.

The first use just shows the basic implementation, while the second shows the use of the custom XML attributes we set up earlier. Notice that to set the username attribute, all we needed to do was add a line in our custom view that said app:username=”{string resource here}”. The code above from our UserInfoView class access and assigns that value.
Now let’s look at the MainActivity class and see how we can dynamically update the code.

Notice for meInfo, we simply find the view, and then have access to the view’s .username, .level, and .logo properties to assign a value.
Result
The result of this code is here:

Notice that we got to repeat the set of views with a logo, username and level multiple times without having to copy and paste that set of views in every spot in our main activity layout file. For groups of views that you know you will use a lot, making a custom view for the design can save repeating code and make your code less error prone. And the benefit doesn’t stop there. This also allows you to create your own edittext or textview where you override its normal functionality, create repeated logic-heavy views in one spot, or even a completely unique view when no pre-built view meets your needs [3]. Custom views allow you to create a fully custom app.
Sources:
[1] “Creating a View Class”, Oct 27, 2021. Accessed on: Nov 4, 2021. [Online]. Available: https://developer.android.com/training/custom-views/create-view
[2] Elye, Building Custom Components with Kotlin, Medium, May 27, 2017. Accessed on: Nov 4, 2021. [Online] Available: https://medium.com/mobile-app-development-publication/building-custom-component-with-kotlin-fc082678b080
[3] “Custom View Components”, Dec 27, 2019. Accessed on: Nov 4, 2021. [Online]. Available: https://developer.android.com/guide/topics/ui/custom-components