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

\

Piyasa Fırsatı
Whiterock Logosu
Whiterock Fiyatı(WHITE)
$0.0001258
$0.0001258$0.0001258
-0.07%
USD
Whiterock (WHITE) Canlı Fiyat Grafiği
Sorumluluk Reddi: Bu sitede yeniden yayınlanan makaleler, halka açık platformlardan alınmıştır ve yalnızca bilgilendirme amaçlıdır. MEXC'nin görüşlerini yansıtmayabilir. Tüm hakları telif sahiplerine aittir. Herhangi bir içeriğin üçüncü taraf haklarını ihlal ettiğini düşünüyorsanız, kaldırılması için lütfen service@support.mexc.com ile iletişime geçin. MEXC, içeriğin doğruluğu, eksiksizliği veya güncelliği konusunda hiçbir garanti vermez ve sağlanan bilgilere dayalı olarak alınan herhangi bir eylemden sorumlu değildir. İçerik, finansal, yasal veya diğer profesyonel tavsiye niteliğinde değildir ve MEXC tarafından bir tavsiye veya onay olarak değerlendirilmemelidir.

Ayrıca Şunları da Beğenebilirsiniz

Jollibee sets Jan. 24 redemption for $300-M securities

Jollibee sets Jan. 24 redemption for $300-M securities

JOLLIBEE FOODS Corp. (JFC) will redeem its $300-million guaranteed senior perpetual capital securities on Jan. 24, 2026, through its wholly owned subsidiary Jollibee
Paylaş
Bworldonline2025/12/16 00:04
XRP Forms 2022-Like RSI Signal, Next Stop: All-Time Highs?

XRP Forms 2022-Like RSI Signal, Next Stop: All-Time Highs?

XRP shows a bullish RSI divergence on the daily chart, similar to 2022, suggesting a possible trend reversal.Read more...
Paylaş
Coinstats2025/12/16 01:13
How to earn from cloud mining: IeByte’s upgraded auto-cloud mining platform unlocks genuine passive earnings

How to earn from cloud mining: IeByte’s upgraded auto-cloud mining platform unlocks genuine passive earnings

The post How to earn from cloud mining: IeByte’s upgraded auto-cloud mining platform unlocks genuine passive earnings appeared on BitcoinEthereumNews.com. contributor Posted: September 17, 2025 As digital assets continue to reshape global finance, cloud mining has become one of the most effective ways for investors to generate stable passive income. Addressing the growing demand for simplicity, security, and profitability, IeByte has officially upgraded its fully automated cloud mining platform, empowering both beginners and experienced investors to earn Bitcoin, Dogecoin, and other mainstream cryptocurrencies without the need for hardware or technical expertise. Why cloud mining in 2025? Traditional crypto mining requires expensive hardware, high electricity costs, and constant maintenance. In 2025, with blockchain networks becoming more competitive, these barriers have grown even higher. Cloud mining solves this by allowing users to lease professional mining power remotely, eliminating the upfront costs and complexity. IeByte stands at the forefront of this transformation, offering investors a transparent and seamless path to daily earnings. IeByte’s upgraded auto-cloud mining platform With its latest upgrade, IeByte introduces: Full Automation: Mining contracts can be activated in just one click, with all processes handled by IeByte’s servers. Enhanced Security: Bank-grade encryption, cold wallets, and real-time monitoring protect every transaction. Scalable Options: From starter packages to high-level investment contracts, investors can choose the plan that matches their goals. Global Reach: Already trusted by users in over 100 countries. Mining contracts for 2025 IeByte offers a wide range of contracts tailored for every investor level. From entry-level plans with daily returns to premium high-yield packages, the platform ensures maximum accessibility. Contract Type Duration Price Daily Reward Total Earnings (Principal + Profit) Starter Contract 1 Day $200 $6 $200 + $6 + $10 bonus Bronze Basic Contract 2 Days $500 $13.5 $500 + $27 Bronze Basic Contract 3 Days $1,200 $36 $1,200 + $108 Silver Advanced Contract 1 Day $5,000 $175 $5,000 + $175 Silver Advanced Contract 2 Days $8,000 $320 $8,000 + $640 Silver…
Paylaş
BitcoinEthereumNews2025/09/17 23:48