1

I'm trying to keep my application clean by breaking functionality into multiple modules.

:App
:Features:Foo
:Features:Bar
:Ux

I've defined my application's theme in themes.xml in the :Ux module, and then it's used throughout the application.

<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light">
   ...
</style>

Some of my features have custom attributes I want to add to the theme and use throughout just that feature, however. So I've added an attrs.xml and themes.xml to each of :Features:Foo and :Features:Bar.

<style name="Theme.MyApp.Foo" parent="Theme.MaterialComponents.Light">
   <item name="customFooViewColor">@android:color/holo_orange_dark</item>   
</style>

and

<style name="Theme.MyApp.Bar" parent="Theme.MaterialComponents.Light">
   <item name="customBarViewColor">@android:color/holo_green_light</item>   
</style>

But now I'd like to add a new feature in :Features:Baz that can host fragments from both :Features:Foo and :Features:Bar, so its theme needs to include the custom attributes defined in :Feature:Foo's attrs.xml and :Feature:Bar's attrs.xml, and the same values of those attributes defined in :Feature:Foo's themes.xml and :Feature:Bar's themes.xml.

One solution is to move those custom attributes and their values into the :Ux module, but that pollutes the entire app with feature-specific properties that only are only required in a couple modules.

As @ritesh4302 points out, I can access the attrs.xml files in :Feature:Foo and :Feature:Bar from :Feature:Baz by adding dependencies on those modules, so another solution is to duplicate all the fields in each of :Features:Foo and :Features:Bar into :Features:Baz.

In :Features:Foo

<style name="Theme.MyApp.Foo" parent="Theme.MaterialComponents.Light">
   <item name="customFooViewColor">@android:color/holo_orange_dark</item>   
</style>

In :Features:Bar

<style name="Theme.MyApp.Bar" parent="Theme.MaterialComponents.Light">
   <item name="customBarViewColor">@android:color/holo_green_light</item>   
</style>

In :Features:Baz

<style name="Theme.MyApp.Baz" parent="Theme.MaterialComponents.Light">
   <item name="customFooViewColor">@android:color/holo_orange_dark</item>   
   <item name="customBarViewColor">@android:color/holo_green_light</item>   
</style>

Obviously this duplication of values is problematic because now I need to update values in multiple places whenever they change.

Is there a way to avoid the duplication without placing everything in :Ux? Has anyone written a build plugin that can achieve this?

1 Answer 1

0

If :Feature:Baz needs to use code written in :Feature:Foo and :Feature:Bar then you need to added them as a dependency and once they are added as dependency you must be able to use the custom attrs defined in base package.

Sign up to request clarification or add additional context in comments.

1 Comment

Makes sense. Any ideas how I can have two custom themes include the same values for those attributes without inheriting from one another?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.