Do I need all three constructors for an Android custom view?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Custom Android views often start simple and then break when used in XML, themes, or preview tools. Constructor overloads are usually the reason. You do not always need three constructors, but you do need the constructor signatures that match how your view will be created.
How Android Chooses a View Constructor
Android can instantiate a view in different ways:
- Programmatic creation from Kotlin or Java code.
- XML inflation from layout files.
- XML inflation with theme style resolution.
Each path maps to a constructor signature. If your class misses a required signature, inflation can fail at runtime with an error that looks unrelated to business logic.
In Java-style custom views, the common constructor set is:
The key point is that all constructors call the same initialization method.
Do You Really Need All Three
A practical decision rule:
- If the view is only created in code, context-only can be enough.
- If the view appears in XML, you need the constructor that accepts
AttributeSet. - If you want style defaults from theme attributes, include
defStyleAttr.
Most production apps eventually need XML plus style support, so the full set is usually the safest long-term choice. It prevents future breakage when someone later adds the view to layout XML or applies a custom style.
Kotlin Pattern with @JvmOverloads
Kotlin lets you keep one primary constructor and still expose overloads for Java and XML paths.
This approach avoids duplicated constructor bodies and keeps parsing logic in one place.
Attribute and Style Handling
If your view supports XML attributes, define them in attrs.xml and parse them once in init logic.
Use defStyleAttr when you want theme-driven defaults. That allows design systems to style the custom view globally instead of setting attributes manually in every layout file.
A strong pattern is:
- Parse XML attributes.
- Apply style defaults.
- Apply hardcoded fallback defaults only last.
This order gives expected behavior across themes and app variants.
Testing Constructor Paths
Test all paths that can create the view:
- Inflate from XML in an Activity.
- Instantiate in code and add to a container.
- Apply custom theme style and verify default values.
Simple instrumentation checks catch constructor regressions early, especially when refactoring legacy views.
Common Pitfalls
- Duplicating setup logic across constructors and creating inconsistent behavior.
- Forgetting to parse
AttributeSetin XML-aware constructor paths. - Ignoring
defStyleAttr, which breaks theme defaults. - Missing
TypedArray.recycle, which causes resource pressure. - Doing heavy work in constructor code instead of lightweight initialization.
Summary
- Provide constructor signatures that match actual creation paths.
- Route all constructors to one shared initialization function.
- Include
AttributeSetanddefStyleAttrfor XML and theme support. - Use Kotlin
@JvmOverloadsto keep code concise and compatible. - Test XML, programmatic, and theme-based instantiation paths.

