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
int
s.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 dependency2: Create the theme object3: 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/v2023-0/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/)[SdkThemeColours](references/v2023-0/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/-sdk-theme-colours/)[CaptureStandaloneThemeColours](references/v2023-0/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/v2023-0/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/)[ProgrammaticTheme.createSdkTheme](references/v2023-0/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic.model/-programmatic-theme/-companion/create-sdk-theme.html)[ProgrammaticTheme.createCaptureStandaloneTheme](references/v2023-0/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/v2023-0/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/v2023-0/android/sensibill-theme-programmatic/-sensibill -runtime -theme -extension/com.getsensibill.themeprogrammatic/programmatic-theme.html)
Limitations
Theme Cannot Be Chaned While an Activity is RunningRuntime 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 ElementsAs 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
ThemingSensibill created AlertDialog
s will have their buttons set to the primary
colour, but will not be additionally styled.