Skip to main content

UI Theme Customization

The Entrupy Android SDK uses Jetpack Compose for its UI and inherits colors and styles from your app's Material Theme. This allows you to align SDK screens with your application's branding without needing a separate theming API.

Overview

The SDK automatically picks up your app's Material 3 (or Material 2) theme. You customize the SDK's appearance by defining your theme in the standard Android way — through XML resources and/or Compose MaterialTheme.

Branding Policy

The Entrupy logo is displayed on SDK screens as part of the branding policy. White-labeling is not permitted. Contact Entrupy for branding configuration details.

1. XML-Based Theme (Activity-Hosted SDK Screens)

SDK screens that launch as activities inherit from your app's XML theme. Define your theme in res/values/themes.xml:

<!-- res/values/themes.xml -->
<resources>
<style name="Theme.YourApp" parent="Theme.Material3.DayNight">
<item name="colorPrimary">@color/your_primary</item>
<item name="colorOnPrimary">@color/your_on_primary</item>
<item name="colorSecondary">@color/your_secondary</item>
<item name="colorOnSecondary">@color/your_on_secondary</item>
<item name="colorSurface">@color/your_surface</item>
<item name="colorOnSurface">@color/your_on_surface</item>
<item name="colorError">@color/your_error</item>
<item name="android:statusBarColor">@color/your_status_bar</item>
</style>
</resources>

Define your color palette in res/values/colors.xml:

<!-- res/values/colors.xml -->
<resources>
<color name="your_primary">#1976D2</color>
<color name="your_on_primary">#FFFFFF</color>
<color name="your_secondary">#FFC107</color>
<color name="your_on_secondary">#000000</color>
<color name="your_surface">#FFFFFF</color>
<color name="your_on_surface">#212121</color>
<color name="your_error">#D32F2F</color>
<color name="your_status_bar">#1565C0</color>
</resources>

2. Compose-Based Theme (Composable SDK Components)

SDK composables such as RegionPreferencesScreen and other SDK screens inherit from the nearest MaterialTheme in your Compose hierarchy:

import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import com.entrupy.sdk.app.EntrupyApp

private val YourColorScheme = lightColorScheme(
primary = Color(0xFF1976D2),
onPrimary = Color.White,
secondary = Color(0xFFFFC107),
onSecondary = Color.Black,
surface = Color.White,
onSurface = Color(0xFF212121),
error = Color(0xFFD32F2F)
)

@Composable
fun MyApp() {
MaterialTheme(colorScheme = YourColorScheme) {
EntrupyApp.sharedInstance().RegionPreferencesScreen(onBack = { /* navigate back */ })
}
}

3. Dark Theme Support

For dark mode, define a night color resource file and the SDK adapts automatically:

<!-- res/values-night/colors.xml -->
<resources>
<color name="your_primary">#90CAF9</color>
<color name="your_on_primary">#000000</color>
<color name="your_surface">#121212</color>
<color name="your_on_surface">#FFFFFF</color>
</resources>

For Compose-based screens, provide a dark color scheme:

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color

private val DarkColorScheme = darkColorScheme(
primary = Color(0xFF90CAF9),
onPrimary = Color.Black,
surface = Color(0xFF121212),
onSurface = Color.White
)

@Composable
fun ThemedEntrupyContent(content: @Composable () -> Unit) {
val colorScheme = if (isSystemInDarkTheme()) DarkColorScheme else YourColorScheme
MaterialTheme(colorScheme = colorScheme) {
content()
}
}

4. Embedding SDK Composables in Fragments and Activities

If your app uses Fragments or Activities with XML layouts (instead of full Compose), wrap SDK composables in a ComposeView:

Fragment Example

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import com.entrupy.sdk.app.EntrupyApp

class RegionPreferencesFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setContent {
MaterialTheme {
EntrupyApp.sharedInstance().RegionPreferencesScreen(onBack = { requireActivity().onBackPressedDispatcher.onBackPressed() })
}
}
}
}
}

Activity Example

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.MaterialTheme
import com.entrupy.sdk.app.EntrupyApp

class EntrupyActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
EntrupyApp.sharedInstance().RegionPreferencesScreen(onBack = { finish() })
}
}
}
}

System Bar Icon Style

By default, the SDK renders light (white) system bar icons (clock, battery, signal indicators), which suits the SDK's dark backgrounds. If your host app uses a light theme, you may want dark icons instead.

Use setStatusBarIconStyle to control the icon appearance across all SDK screens, including bottom sheets and modals:

import com.entrupy.sdk.app.EntrupyApp
import com.entrupy.sdk.model.StatusBarIconStyle

// Call before launching any SDK screen
val entrupyApp = EntrupyApp.sharedInstance()

// Light (white) icons — default, suitable for dark backgrounds
entrupyApp.setStatusBarIconStyle(StatusBarIconStyle.LIGHT)

// Dark (black) icons — suitable for light backgrounds
entrupyApp.setStatusBarIconStyle(StatusBarIconStyle.DARK)
ValueIcon ColorBest For
StatusBarIconStyle.LIGHTWhiteDark backgrounds (default)
StatusBarIconStyle.DARKBlackLight backgrounds
tip

Call setStatusBarIconStyle once during app initialization, before any call to startCapture(), displayDetailViewForItem(), or other SDK screen launchers. The setting persists for the lifetime of the process.

Dynamic Theme Updates

XML Layout with ComposeView

You can also add ComposeView directly in your XML layout:

<!-- res/layout/fragment_region.xml -->
<androidx.compose.ui.platform.ComposeView
android:id="@+id/compose_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
import com.entrupy.sdk.app.EntrupyApp

class RegionPreferencesFragment : Fragment(R.layout.fragment_region) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<ComposeView>(R.id.compose_view).setContent {
MaterialTheme {
EntrupyApp.sharedInstance().RegionPreferencesScreen(onBack = { requireActivity().onBackPressedDispatcher.onBackPressed() })
}
}
}
}
note

Always wrap SDK composables in your app's MaterialTheme so they inherit your color scheme and typography. This applies to all SDK composables including RegionPreferencesScreen.

5. Runtime Theme Changes

Since SDK composables inherit from MaterialTheme, you can switch themes at runtime using Compose state. SDK screens update automatically:

import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import com.entrupy.sdk.app.EntrupyApp

private val LightColors = lightColorScheme(
primary = Color(0xFF1976D2),
onPrimary = Color.White,
surface = Color.White,
onSurface = Color(0xFF212121)
)

private val DarkColors = darkColorScheme(
primary = Color(0xFF90CAF9),
onPrimary = Color.Black,
surface = Color(0xFF121212),
onSurface = Color.White
)

@Composable
fun ThemedApp() {
var isDarkTheme by remember { mutableStateOf(false) }
val colorScheme = if (isDarkTheme) DarkColors else LightColors

MaterialTheme(colorScheme = colorScheme) {
EntrupyApp.sharedInstance().RegionPreferencesScreen(onBack = { /* navigate back */ })
}
}

You can also create seasonal or brand-specific color schemes and swap them the same way — define multiple lightColorScheme() / darkColorScheme() instances and switch between them via state.

6. Accessibility Support

6.1 High Contrast Mode

The SDK respects the system's high contrast settings. To support users who enable high contrast, ensure your color scheme has strong contrast ratios:

import androidx.compose.material3.lightColorScheme
import androidx.compose.ui.graphics.Color

private val HighContrastColors = lightColorScheme(
primary = Color(0xFF000000),
onPrimary = Color(0xFFFFFFFF),
surface = Color(0xFFFFFFFF),
onSurface = Color(0xFF000000),
error = Color(0xFFB00020),
onError = Color(0xFFFFFFFF)
)

6.2 Large Text and Font Scaling

The SDK respects the system font scale. SDK composables use Material Typography, which scales automatically with the user's accessibility settings. No additional configuration is needed.

If you provide custom typography, ensure it uses sp units (scalable pixels) so font scaling works:

import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.sp

val AccessibleTypography = Typography(
bodyLarge = TextStyle(fontSize = 16.sp),
bodyMedium = TextStyle(fontSize = 14.sp),
labelLarge = TextStyle(fontSize = 14.sp)
)

@Composable
fun AccessibleEntrupyContent(content: @Composable () -> Unit) {
MaterialTheme(typography = AccessibleTypography) {
content()
}
}

6.3 Content Descriptions

SDK screens provide built-in content descriptions for screen readers (TalkBack). Interactive elements — buttons, images, form fields — include semantic descriptions for accessibility.

If you embed SDK composables inside your own UI, ensure your surrounding layout also follows accessibility best practices:

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics

@Composable
fun AccessibleRegionView() {
Column {
Text(
text = "Region Preferences",
modifier = Modifier.semantics {
contentDescription = "Region preferences section"
}
)
EntrupyApp.sharedInstance().RegionPreferencesScreen(onBack = { /* navigate back */ })
}
}

7. Testing Theme Customization

7.1 Theme Preview

Use Jetpack Compose Preview to verify your theme with SDK composables before running on a device:

import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview

@Preview(name = "Light Theme", showBackground = true)
@Composable
fun PreviewLightTheme() {
MaterialTheme(colorScheme = LightColors) {
// Preview your themed layout here
// Note: SDK composables require initialization, so preview
// your theme wrapper without the SDK for visual verification
}
}

@Preview(name = "Dark Theme", showBackground = true, uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES)
@Composable
fun PreviewDarkTheme() {
MaterialTheme(colorScheme = DarkColors) {
// Preview dark theme layout
}
}

7.2 Theme Validation Checklist

Before publishing your themed integration, verify:

  • Color contrast: Primary/onPrimary and surface/onSurface pairs meet WCAG AA minimum contrast ratio (4.5:1 for normal text, 3:1 for large text).
  • Dark mode: All SDK screens are legible in both light and dark modes.
  • Font scaling: Enable "Largest" font size in Android accessibility settings and verify SDK screens remain usable.
  • Screen reader: Enable TalkBack and navigate through SDK screens to verify all interactive elements are announced.
  • Orientation: Test SDK screens in both portrait and landscape.

8. Best Practices

  • Apply your theme before SDK initialization. Ensure your Application theme is set in your AndroidManifest.xml before EntrupyApp.init(this) is called.
  • Ensure adequate contrast. Test color combinations for readability, especially between primary/onPrimary and surface/onSurface pairs.
  • Test in both light and dark modes. SDK screens should be legible in both configurations.
  • Use Material 3 where possible. The SDK is built with Material 3 components for the best visual consistency.
  • Wrap composables in MaterialTheme when embedding in Fragments or Activities via ComposeView.

Next Steps