Skip to content

Building a UI Module with Reusable UI Components & Styles using Views

Last Updated 2025-08-25 UTC+8.

In the realm of software development, creating reusable components and styles is paramount for efficiency, consistency, and maintainability. By modularizing UI elements such as components, themes, attributes, colors, styles, and strings, developers can streamline their workflow, enhance code reusability, and foster a more cohesive user experience across application(s).

WARNING

Not all projects are suitable for the development of a UI Module, as it could introduce unnecessary complexity, especially for smaller apps. Carefully weigh the pros and cons before making your decision.

Why do we need a UI Module?

A UI module functions as a self-contained entity that encapsulates reusable user interface components, styles, themes, attributes, and other design elements. It serves as a modular building block that can be seamlessly integrated into different parts of our application(s). There are various reasons why we would like to build and use a UI module:

AdvantageExplanation
ReusabilityModularizing UI components enables effortless reuse within and across diverse projects, eliminating the need to reconstruct the same component multiple times and significantly reducing development time and effort.
MaintainabilityBy separating concerns, maintaining the codebase becomes more straightforward. For instance, when UI design alterations are required for a component used in multiple areas of an application, updating the component within the UI module suffices, sparing the need to search and modify all instances of its usage.
ScalabilityWith pre-built UI components in place, scaling the application, e.g., adding more screens for additional features, merely involves reusing the existing components, facilitating seamless scalability without necessitating a complete restart, all while maintaining clean code.
TestabilityIsolating the UI section for testing from other code segments simplifies the testing process, allowing for independent testing of the user interface without interference from the application logic.
ConsistencyUtilizing the same component across various screens within an application and even spanning different applications within the organization guarantees a uniform appearance and interaction throughout the user journey, enhancing user experience and upholding brand identity.

Building Blocks

Here are the important building blocks of a UI Module for Android mobile app development using Views:

WARNING

In my opinion, there's no right or wrong answer on how to utilize each building blocks because different projects have different requirements, and different developers have different preferences. Below is the approach I would prefer to follow for my use cases. Please only take it as a reference instead of regarding it as a strict guideline.

Building BlockDescriptionMy Suggested Coding Approach for UI Module
ThemesDefine the set of UI attributes that would be applied to the entire app, activity, or view hierarchy (by specifying the theme in the Manifest / XML layout files).

A theme could include:
(1) Android's default attributes, e.g., android:statusBarColor, windowActionBar, etc.;
(2) Attributes from the parent theme, and;
(3) Self-defined attributes from attrs.xml.
Setup
- Create the themes.xml file in your res/values folder.
- Use the <style> tag to define your own theme & use a theme from Theme.MaterialComponents as the parent theme.

Details
- Override the Android's default attributes for system-related controls, e.g., window, navigation bar, or status bar.
- Prepare self-defined attributes in attrs.xml and set it in themes.xml. This could be useful in some use cases, e.g., for practicing color management.
AttributesDefine:
(1) Attributes for reusable UI components
(2) General attributes, e.g., colors, which you would like the app-level code to be able to customize.
Setup
- Create the attrs.xml file in your res/values folder.

Details
- Use the <declare-styleable> and <attr> tags for defining the customizable properties of various reusable UI components. Obtain their values programmatically using context.obtainStyledAttributes(attr, R.styleable.XXX) in Kotlin.
- Use the <attr> tag to declare general attributes, e.g., colors, which are to be defined in module-level themes.xml and overrided in app-level's themes.xml for customizable appearance or behaviour of UI elements.
ColorsDefine a color palette, for light & dark mode correspondingly, to be used throughout application(s).Setup
- Create the colors.xml file in your res/values folder for light mode.
- Create the colors.xml file in your res/values-night folder for dark mode.

Details
- Use the <color> tag to define a color.
- Preferably do not use the colors declared in this file directly in XML or Kotlin file. Instead, use it in themes.xml with @color/XXX, and obtain it using:

1. val typedValue = TypedValue()
2. context.theme.resolveAttribute(themeAttr, typedValue, true)
3. typedValue.data or typedValue.resourceId

in Kotlin, and using ?attr/XXXXX in XML files.
StylesDefine sets of attributes to be applied to UI elements.

Since in a UI module, we have grouped the attributes via preparing reusable UI components already, I would only use this file for defining TextAppearance, which includes general-purpose text styles ONLY, e.g., Heading1, Body, etc. (do not include unique text styles used within a specific reusable UI element).
Setup
- Create the styles.xml file in your res/values folder.

Details
- Declare a base TextAppearance inheriting from a parent TextAppearance style e.g., TextAppearance.AppCompat.
- Declare a new TextAppearance using the dot syntax, e.g., MyBaseTextAppearance.Heading1.
- Use the <style> tag for declaring a TextAppearance.
- Use the <item> tag for declaring the attributes to be used for a particular TextAppearance.
- Use the TextAppearance in XML files via android:TextAppearance="@style/MyTextAppearance.XXX, or, in Kotlin files via setTextAppearance(R.Style.MyTextAppearance_XXX).
StringsStore any text strings that would be displayed in the UI for localization and centralized text management purposes.Setup
- Create the strings.xml file in your res/values folder.
- You can have different strings.xml file for differnet locale.

Details
- Use the <string> tag to declare a text string.
- Get the string resource in XML files via @string/XXX and in Kotlin files via context.getString(R.string.XXX).
DimensionsDefine and centralize commonly used dimensions for layouts and texts, e.g., margins, paddings, text sizes, etc.Setup
- Create the dimens.xml file in your res/values folder.

Details
- Use the <dimen> tag to declare a dimension.
- Refer to this blog post for more details about how to handle dimensions.
Kotlin + XMLImplement reusable UI components via Kotlin classes that extends existing View classes and handle component-specific UI logic. We can prepare the layouts with XML, declare the customizable attributes of the UI component in attrs.xml using <declare-styleable>, and set the customized attributes via Kotlin code.Setup
- Create a Kotlin class file extending existing View classes e.g., class MyComponent @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout(context, attrs, defStyleAttr).
- Create XML file(s) for the component's layout if needed.

Details
- Inflate the XML layout from Kotlin's init block, and handle any attributes setup.
- Prepare methods needed to handle component-specific UI logic.
- Use themes.xml, attrs.xml, and colors.xml files for color management if needed.
- Use dimens.xml for layout and text sizes.

Color Management Strategy

Colors play a pivotal role in capturing user attention within an interface. In the realm of UI modules, various applications that incorporate these modules may necessitate distinct color schemes while upholding a consistent design language. In such scenarios, it becomes imperative to establish a flexible mechanism for tailoring the color palette of our diverse layouts and reusable UI components. This is where a Color Management Strategy comes into play.

Proposed Strategy

Here is one proposed approach to manage colors within a UI module that make use of themes.xml, attrs.xml, and colors.xml:

  1. Define a theme in themes.xml in the UI module.

    xml
    <style name="Theme.MyModule" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- We will declare theme attributes here later. -->
    </style>
  2. Define a color attributes in attrs.xml in the UI module. E.g.,

    xml
    <attr name="myTextColor" format="color" />
  3. Define the colors in light and dark modes in colors.xml file of the UI module. E.g.,

    xml
    <color name="my_text">#E91E63</color>
    xml
    <color name="my_text">#980E3E</color>
  4. Define the default color of the color attributes in themes.xml. E.g.,

    xml
    <style name="Theme.MyModule" parent="Theme.MaterialComponents.Light.NoActionBar">
        <item name="myTextColor">@color/my_text</item>
    </style>
  5. Use the theme attributes in any layouts or UI components within the UI module. E.g.,

    xml
    <TextView
        ...
        android:textColor="?attr/myTextColor"
        />

With this approach, in case we need to override the colors, we simply need to override it in the app-level's themes.xml file. E.g.,

xml
<style name="Theme.MyApp" parent="Theme.MyModule">
    <item name="myTextColor">@color/my_custom_text</item>
</style>

By following this approach, we can enhance flexibility in color management, and enable easier customization and theming.

Best Practices

  • We should use the <merge> tag whenever our reusable UI component doesn't require a root view. This is to remove unnecessary nested layouts, optimize view hierarchy, and hence improve UI performance.
  • Always extract strings used into the strings.xml file.
  • Always use a consistent naming convention for the same type of resource. E.g., file naming with ic_XXX / bg_XXX / etc., or, attribute names in CamelCase with a prefix of the module name, etc. Follow your company's guidelines.

References

  1. Android Developers. (2025, August 20). Styles and themes. https://developer.android.com/develop/ui/views/theming/themes
  2. Rich Schuler. (2010, August 9). Defining custom attrs. https://stackoverflow.com/questions/3441396/defining-custom-attrs
  3. Android Developers. (2025, February 10). String resources. https://developer.android.com/guide/topics/resources/string-resource