Android Runtime Theme

Purpose

In certain special cases, the theme colours may not be known at compile time. In such cases, runtime theming of the Android SDK will be required.

This functionality is supported by the Sensibill Android SDK but not recommended, and should only be used if absolutely necessary.

Implementation

Info

It is advised that the runtime theme be set before starting the SensibillSDK

Info

All colours used in the ProgrammaticTheme model must be @ColorInt ints.
eg.
// Yes
colour = getColor(R.color.myColour) // ✔
colour = Color.parseColor("#FF0000") // ✔

// No
colour = R.color.myColour // ✘
colour = "#FF0000" // ✘

Info

Please read and be aware of the limitations of our runtime theming implementation before continuing with your implementation.

In order to implement runtime theming, please follow the following guide

Overview

The overall steps for implementing runtime theming are simple, at a glance, they are:

1: Add the required dependency
2: Create the theme object
3: Apply the theme object to the SensibillSDK

Add Additional Dependency

Android Runtime Theming functionality is not included in the default Sensibill SDK modules. In order to enable runtime theming support, please add the following Sensibill library to your app level build.gradle file:

dependencies {
    // ...

    // Add below other Sensibill dependencies
    implementation "com.getsensibill:sensibill-theme-programmatic:$sensibillSdkVersion"

    // ...
}

Create Theme

First, a ProgrammaticTheme model must be created. This model contains every colour used in the Sensibill SDK Theme.

When runtime theming is active, all xml themed colours (from Theme.Sensibill) will be replaced by the colours within the ProgrammaticTheme model provided.

There are two ways to create a ProgrammaticTheme, which will be outlined below.

From Scratch

When creating a runtime theme from scratch, every colour must be provided.

Create a new instance of ProgrammaticTheme as follows:

val theme = ProgrammaticTheme(
    ProgrammaticTheme.SdkThemeColours(
        getColor(R.color.testColourPrimary),
        getColor(R.color.testColourPrimaryVariant),
        getColor(R.color.testColourOnPrimary),
        getColor(R.color.testColourSecondary),
        getColor(R.color.testColourOnSecondary),
        getColor(R.color.testColourBackground),
        getColor(R.color.testColourOnBackground),
        getColor(R.color.testColourSurface),
        getColor(R.color.testColourSurfaceVariant),
        getColor(R.color.testColourOnSurface),
        getColor(R.color.testColourOnSurfaceFocus),
        getColor(R.color.testColourError),
        getColor(R.color.testColourOnError)
    ),
    ProgrammaticTheme.CaptureStandaloneThemeColours(
        getColor(R.color.testColourCaptureBackground),
        getColor(R.color.testColourOnCaptureBackground),
        getColor(R.color.testColourOnCaptureBackgroundDisabled)
    )
)
final ProgrammaticTheme theme = new ProgrammaticTheme(
        new ProgrammaticTheme.SdkThemeColours(
                getColor(R.color.testColourPrimary),
                getColor(R.color.testColourPrimaryVariant),
                getColor(R.color.testColourOnPrimary),
                getColor(R.color.testColourSecondary),
                getColor(R.color.testColourOnSecondary),
                getColor(R.color.testColourBackground),
                getColor(R.color.testColourOnBackground),
                getColor(R.color.testColourSurface),
                getColor(R.color.testColourSurfaceVariant),
                getColor(R.color.testColourOnSurface),
                getColor(R.color.testColourOnSurfaceFocus),
                getColor(R.color.testColourError),
                getColor(R.color.testColourOnError)
        ),
        new ProgrammaticTheme.CaptureStandaloneThemeColours(
                getColor(R.color.testColourCaptureBackground),
                getColor(R.color.testColourOnCaptureBackground),
                getColor(R.color.testColourOnCaptureBackgroundDisabled)
        )
);

[ProgrammaticTheme](references/v2025/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/)
[SdkThemeColours](references/v2025/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/-sdk-theme-colours/)
[CaptureStandaloneThemeColours](references/v2025/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/-capture-standalone-theme-colours/)

Overriding defaults

If only some theme colours need to be overridden, the additional helper functions ProgrammaticTheme.createSdkTheme() and ProgrammaticTheme.createCaptureStandaloneTheme() can be used. These functions will use the colour values existing in the Theme.Sensibill style when no (or null) value is given for a specific theme colour.

Here is an example where only the primary and secondary colours need to be overridden:

// Given that (this is Context) == true
val theme = ProgrammaticTheme(
    ProgrammaticTheme.createSdkTheme(
        this,
        colourPrimary = getColor(R.color.testColourPrimary),
        colourSecondary = getColor(R.color.testColourSecondary)
    ),
    ProgrammaticTheme.createCaptureStandaloneTheme(this)
)
// Given that (this instanceof Context) == true
final ProgrammaticTheme theme = new ProgrammaticTheme(
        ProgrammaticTheme.Companion.createSdkTheme(
                this,
                getColor(R.color.testColourPrimary),
                null,
                null,
                getColor(R.color.testColourSecondary),
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
        ),
        ProgrammaticTheme.Companion.createCaptureStandaloneTheme(this, null, null, null)
);

[ProgrammaticTheme](references/v2025/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/)
[ProgrammaticTheme.createSdkTheme](references/v2025/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/-companion/create-sdk-theme.html)
[ProgrammaticTheme.createCaptureStandaloneTheme](references/v2025/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/-companion/create-capture-standalone-theme.html)

Apply Theme

In order to apply a runtime theme that you have created, the following SensibillSDK extension can be used:

val theme: ProgrammaticTheme // Created above
SensibillSDK.programmaticTheme = theme
final ProgrammaticTheme theme; // Created above
ProgrammaticThemePluginKt.setProgrammaticTheme(SensibillSDK.INSTANCE, theme);

[SensibillSDK.programmaticTheme](references/v2025/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic/programmatic-theme.html)

(If Required) Remove Theme

In order to remove an applied runtime theme, simply set the theme to null:

SensibillSDK.programmaticTheme = null
ProgrammaticThemePluginKt.setProgrammaticTheme(SensibillSDK.INSTANCE, null);

[SensibillSDK.programmaticTheme](references/v2025/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic/programmatic-theme.html)

Limitations

Theme Cannot Be Chaned While an Activity is Running
Runtime Theming is only applied on Activity creation, therefore, if the theme is changed while a Sensibill Activity is running, the theme will not be applied.

It is recommended that the runtime theme be applied before starting any Sensibill Activities, however, if it is required, any running Sensibill Activity should be restarted (Activity.recreate())

No Ability To Restyle Specific Elements
As the runtime theming is applied manually and programmatically, if a runtime theme is being used, any colour customization of the Sensibill SDK ui via overriding style attributes will be ignored. Please keep this in mind if implementing the runtime theme.

AlertDialog Theming
Sensibill created AlertDialogs will have their buttons set to the primary colour, but will not be additionally styled.