Dynamic theming is a powerful technique for Android apps that need flexible branding. In scenarios like white-label products, enterprise clients, or apps that fetch custom settings from a server, being able to update colors at runtime can save you from maintaining multiple static themes or shipping new builds. In this article, we will explore two practical ways to apply server-defined color schemes in XML-based Android UIs.Dynamic theming is a powerful technique for Android apps that need flexible branding. In scenarios like white-label products, enterprise clients, or apps that fetch custom settings from a server, being able to update colors at runtime can save you from maintaining multiple static themes or shipping new builds. In this article, we will explore two practical ways to apply server-defined color schemes in XML-based Android UIs.

Simple Dynamic Color Schemes in Android Applications

2025/09/02 15:06

Dynamic theming is a powerful technique for Android apps that need flexible branding. In scenarios like white-label products, enterprise clients, or apps that fetch custom settings from a server, being able to update colors at runtime can save you from maintaining multiple static themes or shipping new builds.

In this article, we will explore two practical ways to apply server-defined color schemes in XML-based Android UIs:

  • Manual View Theming
  • Using LayoutInflater.Factory2 We will compare the two approaches in terms of scalability, maintainability, and complexity, and also look briefly at how Jetpack Compose makes dynamic theming first-class.

What Are Dynamic Color Schemes?

A dynamic color scheme lets your app load and apply a palette at runtime, based on user preferences, company branding, or remote configuration. Instead of hardcoding styles or toggling between predefined themes, the app adapts its appearance dynamically, keeping the UI consistent with the source of truth on the server.

Example server response:

{   "primary": "#006EAD",   "secondary": "#00C853",   "background": "#FFFFFF",   "surface": "#F5F5F5",   "onPrimary": "#FFFFFF" } 

(A real-world payload would likely include more fields.)

Setup

We’ll define a simple model to represent our theme colors (omitting DTOs and converters for brevity):

data class ThemeColors(     val primary: Int,     val secondary: Int,     val background: Int,     val surface: Int,     val onPrimary: Int ) 

Approach 1: Manual View Theming

How It Works

After inflating a layout, you manually apply colors to each view using findViewById, setBackgroundColor, setTextColor, etc.

Example:

class MainActivity : AppCompatActivity() {      private val themeColors = ThemeColorsRepository.get( /* from server */ )      override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)          val root = findViewById<ViewGroup>(R.id.rootLayout)         val toolbar = findViewById<Toolbar>(R.id.toolbar)         val titleText = findViewById<TextView>(R.id.titleText)          toolbar.setBackgroundColor(themeColors.primary)         toolbar.setTitleTextColor(themeColors.onPrimary)         root.setBackgroundColor(themeColors.background)         titleText.setTextColor(themeColors.primary)     } } 

✅ Pros

  • Beginner-friendly and easy to debug.
  • Great for prototypes or theming a few views.

❌ Cons

  • Tedious in multi-screen apps.
  • Easy to miss views and lose consistency.
  • Doesn’t scale well.

Approach 2: Using LayoutInflater.Factory2

What Is It?

LayoutInflater.Factory2 is a lesser-known but powerful Android API. It lets you intercept view inflation globally and apply logic (like theming) as views are created.

How It Works

Instead of styling views manually, you “wrap” the inflation process and automatically apply colors to views as they’re inflated from XML.

Example

class ThemingFactory(     private val baseFactory: LayoutInflater.Factory2?,     private val themeColors: ThemeColors ) : LayoutInflater.Factory2 {      override fun onCreateView(parent: View?, name: String, context: Context, attrs: AttributeSet): View? {         val view = baseFactory?.onCreateView(parent, name, context, attrs)             ?: LayoutInflater.from(context).createView(parent, name, null, attrs)          applyDynamicTheme(view)         return view      }      override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {         return onCreateView(null, name, context, attrs)     }      private fun applyDynamicTheme(view: View?) {         when (view) {             is TextView -> view.setTextColor(themeColors.primary)             is Button -> {                 view.setBackgroundColor(themeColors.primary)                 view.setTextColor(themeColors.onPrimary)             }             is Toolbar -> {                 view.setBackgroundColor(themeColors.primary)                 view.setTitleTextColor(themeColors.onPrimary)             }         }     } } 

Installation

This must be set before setContentView:

override fun onCreate(savedInstanceState: Bundle?) {     val themeColors = ThemeColors(/* from server */)      val inflater = LayoutInflater.from(this)     val baseFactory = inflater.factory2     LayoutInflaterCompat.setFactory2(inflater, ThemingFactory(baseFactory, themeColors))      super.onCreate(savedInstanceState)     setContentView(R.layout.activity_main) } 

⚠️ Gotcha: With AppCompatActivity, the inflater is overridden internally. If you don’t delegate back to the default AppCompat factory, you’ll lose default styling. A working sample is available here:

  • HomeActivity.kt
  • ThemingFactory.kt

Manual vs Factory2: Feature Comparison

| Feature | Manual View Theming | LayoutInflater.Factory2 Theming | |----|----|----| | Ease of implementation | ✅ Beginner-friendly | ⚠️ Intermediate | | Control per view | ✅ Total | ⚠️ Needs conditionals per view type | | Scalability | ❌ Poor (per view) | ✅ Excellent (global, centralized) | | Boilerplate | ❌ High | ✅ Low | | Reusability | ❌ Limited | ✅ Easy to reuse across screens | | Custom view theming | ❌ Manual only | ✅ Interceptable during inflation | | Dynamic theme switching | ⚠️ Manual re-theming required | ⚠️ Needs re-inflation or restart |

In practice: I applied theming to a large app with dozens of screens in four weeks using LayoutInflater.Factory2. A manual approach would have taken far longer.

Bonus Section: Compose

Jetpack Compose makes it natural to create and apply a custom MaterialTheme dynamically, so you can swap colors at runtime (for example, after fetching them from your server).

Example of implementation:

  1. Define a ThemeColors model (just like in the XML-based version).
  2. Expose it from a ViewModel using StateFlow or LiveData.
  3. Wrap your UI with a MaterialTheme whose colorScheme is derived from ThemeColors.
  4. All Composables that use MaterialTheme.colorScheme will automatically recompose when colors change.

| XML + Factory2 | Jetpack Compose | |----|----| | Manual theming of views (per type) | Global theming via MaterialTheme | | Requires inflating and intercepting views | Native support with recomposition | | Boilerplate-heavy | Minimal, declarative | | Great for legacy codebases | Best for Compose-first apps |

In short, Compose makes dynamic theming a first-class feature, while XML requires custom plumbing (via LayoutInflater.Factory2 or manual updates).

Sample project: Dynamic Theme in Compose

Conclusion

All of the mentioned approaches unlock server-driven dynamic theming, but each fits different needs:

  • Manual theming: Best for small apps, quick prototypes, or theming just a few views.
  • LayoutInflater.Factory2: The way to go for scalable, brand-flexible apps (white-label, multi-client).
  • Jetpack Compose: Dynamic theming is built-in and declarative, ideal for new projects. If you’re working on a legacy XML app, Factory2 will save you huge amounts of time. For new apps, Compose + MaterialTheme is the clear winner.

Further Reading

  • Android Docs: LayoutInflater.Factory2
  • Sample project

\

Disclaimer: The articles reposted on this site are sourced from public platforms and are provided for informational purposes only. They do not necessarily reflect the views of MEXC. All rights remain with the original authors. If you believe any content infringes on third-party rights, please contact [email protected] for removal. MEXC makes no guarantees regarding the accuracy, completeness, or timeliness of the content and is not responsible for any actions taken based on the information provided. The content does not constitute financial, legal, or other professional advice, nor should it be considered a recommendation or endorsement by MEXC.

You May Also Like

Mutuum Finance (MUTM) Holder Count Explodes as Phase 6 Nears 100% Allocation Ahead of Q1 Protocol Launch, Best Crypto to Buy?

Mutuum Finance (MUTM) Holder Count Explodes as Phase 6 Nears 100% Allocation Ahead of Q1 Protocol Launch, Best Crypto to Buy?

The post Mutuum Finance (MUTM) Holder Count Explodes as Phase 6 Nears 100% Allocation Ahead of Q1 Protocol Launch, Best Crypto to Buy? appeared on BitcoinEthereumNews.com. Mutuum Finance is gaining attention among investors, particularly given the fact that the project is witnessing an extremely high number of new holders as the project is fast entering the last stage of Phase 6 of the presale, which is soon to attain 100% sales. Mutuum Finance (MUTM) is currently the best crypto to buy. MUTM is primed and ready to capitalize on the extremely awaited V1 protocol launch, towards the end of Q4, which expresses the project’s attention towards the implementation of usability. With the extremely low price, which is merely $0.035 today, the project continues to see increased attention. Having attained more than $19.18 million in presale and having garnered more than 18,350 supporters, Mutuum Finance is currently the best crypto among new buyers. Boosting the Presale Process with More Investors Entering Phase 6 Mutuum Finance is among the most-watched blockchain initiatives on the eve of the new year, 2026. The ongoing presale is attracting a lot of attention, and so far, it has gained more than 18,350 members and has exceeded the $19.18 million mark. The cost of buying tokens in phase 6 is $0.035, before phase 7, which is set to raise prices by nearly 20% to $0.04. The project has gained so much traction because it focuses on financial applications and utilization, rather than creating hype. This is what has made MUTM so attractive to financial investors, who look at utility focus when searching for new investments and looking to buy the best crypto. Ready to Go Live on Sepolia Testnet Mutuum Finance is preparing to launch the V1 protocol on the Sepolia testnet, which will take place during Q4 2025. This is a long-awaited moment, marking an essential milestone regarding the technical part of the project. When it happens, the most basic components of…
Share
BitcoinEthereumNews2025/12/08 15:54
Whales Dump 200 Million XRP in Just 2 Weeks – Is XRP’s Price on the Verge of Collapse?

Whales Dump 200 Million XRP in Just 2 Weeks – Is XRP’s Price on the Verge of Collapse?

Whales offload 200 million XRP leaving market uncertainty behind. XRP faces potential collapse as whales drive major price shifts. Is XRP’s future in danger after massive sell-off by whales? XRP’s price has been under intense pressure recently as whales reportedly offloaded a staggering 200 million XRP over the past two weeks. This massive sell-off has raised alarms across the cryptocurrency community, as many wonder if the market is on the brink of collapse or just undergoing a temporary correction. According to crypto analyst Ali (@ali_charts), this surge in whale activity correlates directly with the price fluctuations seen in the past few weeks. XRP experienced a sharp spike in late July and early August, but the price quickly reversed as whales began to sell their holdings in large quantities. The increased volume during this period highlights the intensity of the sell-off, leaving many traders to question the future of XRP’s value. Whales have offloaded around 200 million $XRP in the last two weeks! pic.twitter.com/MiSQPpDwZM — Ali (@ali_charts) September 17, 2025 Also Read: Shiba Inu’s Price Is at a Tipping Point: Will It Break or Crash Soon? Can XRP Recover or Is a Bigger Decline Ahead? As the market absorbs the effects of the whale offload, technical indicators suggest that XRP may be facing a period of consolidation. The Relative Strength Index (RSI), currently sitting at 53.05, signals a neutral market stance, indicating that XRP could move in either direction. This leaves traders uncertain whether the XRP will break above its current resistance levels or continue to fall as more whales sell off their holdings. Source: Tradingview Additionally, the Bollinger Bands, suggest that XRP is nearing the upper limits of its range. This often points to a potential slowdown or pullback in price, further raising concerns about the future direction of the XRP. With the price currently around $3.02, many are questioning whether XRP can regain its footing or if it will continue to decline. The Aftermath of Whale Activity: Is XRP’s Future in Danger? Despite the large sell-off, XRP is not yet showing signs of total collapse. However, the market remains fragile, and the price is likely to remain volatile in the coming days. With whales continuing to influence price movements, many investors are watching closely to see if this trend will reverse or intensify. The coming weeks will be critical for determining whether XRP can stabilize or face further declines. The combination of whale offloading and technical indicators suggest that XRP’s price is at a crossroads. Traders and investors alike are waiting for clear signals to determine if the XRP will bounce back or continue its downward trajectory. Also Read: Metaplanet’s Bold Move: $15M U.S. Subsidiary to Supercharge Bitcoin Strategy The post Whales Dump 200 Million XRP in Just 2 Weeks – Is XRP’s Price on the Verge of Collapse? appeared first on 36Crypto.
Share
Coinstats2025/09/17 23:42