2

I am creating my own custom view.

Here is the code for MyCustomView.java

    package com.krish.customviews
    import...
    
    public class MyCustomView extends FrameLayout{
          public MyCustomView(@NonNull Context context){
               super(context);
               init();

          }
          public MyCustomView(@NonNull Context context, @Nullable AttributeSet attrs){
               super(context, attrs);
               init();

          }
          public MyCustomView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr){
               super(context, attrs, defStyleAttr);
               init();

          }
          private void init(){
          }
            
    }

And my main_layout.xml file:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<com.krish.MyCustomView> 

//layout attributes


/>

My question is: If I change the attributes of the custom view in the .xml file, will the 2nd or 3rd constructor of MyCustomView.java file be called?

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
CodingChap
  • 1,088
  • 2
  • 10
  • 23

2 Answers2

3

As described by @Zain answer the two-argument constructor is called when the layout is inflated from XML.

  • The defStyleAttr is the default style. It doesn’t directly point to a style, but lets you point to one of the attributes defined in your theme.
    If you’re subclassing a widget and not specifying your own default style then be sure to use the parent classes default style in your constructors (don’t just pass 0). It can be 0 only to not look for defaults.
    For example in the MaterialButton: R.attr.materialButtonStyle

  • The defStyleRes is a resource identifier of a style resource that supplies default values for the view, used only if defStyleAttr is 0 or can not be found in the theme. Can be 0 to not look for defaults.
    For example in the MaterialButton: R.style.Widget_MaterialComponents_Button

The AttributeSet parameter can essentially be thought of as a map of the XML parameters you specify in your layout.
Keep in mind the styling precedence order:

When determining the final value of a particular attribute, there are four inputs that come into play:

  • Any attribute values in the given AttributeSet.
  • The style resource specified in the AttributeSet (named "style").
  • The default style specified by defStyleAttr and defStyleRes
  • The base values in this theme.
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
2

The two-argument constructor is the only needed when you access the custom view from XML.

View(Context context, AttributeSet attrs)

The 3 & 4 argument constructors are meant to be called by super classes to provide default style via theme attribute and direct default style resource.

View(Context context, AttributeSet attrs, int defStyleAttr)
View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
  • The defStyleAttr parameter is the reference to a style attribute defined in the theme.
  • The defStyleRes parameter is the reference to the default style defined in styles.xml. Don't worry, if this explanation is unsatisfying to you. I will go deeper into details in the section about attributes and styles.

Source back to this article

You can also have a look at this question

Zain
  • 37,492
  • 7
  • 60
  • 84