Johann Muller
Johann Muller

Reputation: 175

Android compose - modular app design - how to manage theming?

I'm working on modularizing a test application with Android Compose and have the application stuff woking well, however it seems that if you want to add custom theming like colors and fonts you run into problems.

So as example under the app/src/main/java/com/xx/myapp/theme/ we extend Color.kt

val Green900 = Color(0XFF242d2d)
val Green800 = Color(0XFF354242)

val Colors.green800: Color
    @Composable
    get() = Green800

val Colors.green700: Color
    @Composable
    get() = Green700

Now trying to use these in any of the "Modules" is not possible and the only way I can see is to duplicate the whole theme structure in each module which seems stupid?

So if I have a module in the structure as example components/src/main/java/com/xx/components/BottomNavBar.kt I cannot use

selectedContentColor = MaterialTheme.colors.gray800,

unless I duplicate the Color.kt inside this module OR I include the "app" module inside the build.gradle.kts for this module...

 "implementation"(project(Modules.app))

which will cause a "Circular dependency" if I'm not mistaken

Any suggestions on how to manage this without duplication?

Thanks J

Upvotes: 2

Views: 1207

Answers (2)

Captain Allergy
Captain Allergy

Reputation: 86

In your ui.theme folder that includes Color.kt, Shape.kt, Theme.kt and Type.kt you will need to define your colors in Color.kt

val Green900 = Color(0XFF242d2d)
val Green800 = Color(0XFF354242)

In your Theme.kt you define your general Theme for the whole App that my look like this:

@Composable
fun AppTheme(content: @Composable() () -> Unit) {

    MaterialTheme(
        colors = LightColorPalette,
        typography = Typography,
        shapes = Shapes,
        content = content
    )
}

And also:

val LightColorPalette = lightColors(
    primary = Green900,
    primaryVariant = Green800,
    secondary = Green200

    /* Other default colors to override
    background = Color.White,
    surface = Color.White,
    onPrimary = Color.White,
    onSecondary = Color.Black,
    onBackground = Color.Black,
    onSurface = Color.Black,
    */
)

As you can see you can define all of your desired surfaces, backgrounds etc with a color that you defined and later use it like this:

MaterialTheme.colors.primary

You can also have a look here on the official documentation

Upvotes: -2

kingston
kingston

Reputation: 11419

From what I have understood one way to do it is to have a module only for the shared definitions in such a way that you do not need to import the entire app module. This shared module will of course be imported by the app module as well.

More in general everytime you have a circular dependency you need to check whether the solution can be to split the modules in smaller ones in such a way that you break the circle.

Upvotes: 1

Related Questions