DEV Community

Cover image for First steps using Material3 in a WearOS Android App
Marlon López
Marlon López

Posted on • Edited on

First steps using Material3 in a WearOS Android App

Would you like your WearOS app to have the same modern and sophisticated look as the latest Android apps? Material Design 3, design system built and supported by Google, has already transformed the look and feel of millions of apps. Now, it’s your wearable apps’ turn. Although the library responsible for applying material3 in WearOS is still in alpha phase, this new specification promises to take smartwatch user interfaces to the next level.

In the following text, I will share some aspects to take into account when changing from current material design system library to material3 in our Android applications for WearOS.

About WearOS Compose Material 3 Library

This library makes it easier for developers to write Jetpack Compose applications for Wearable devices that implement Wear Material 3 Design UX guidelines and specifications.

Let's start the migration

In Android studio, create a new project that generates a WearOS App. you can check the instructions from the Android Official Guide, After created, lets check that the the app is successfully built and running in an emulator or phisical wearable device.

Adding the Wear Compose Material 3 library

When moving from the actual Wear Compose Material library to the Material3 one, its important to note that, at the time of writing, it was straightforward to change the composables used, just be careful with this, not all composables available in the material2 version have the corresponding material3 composable for WearOS.

Android Wear Compose Material 3 library can be installed using the instructions from Maven central.

dependencies {
  ...
  implementation("androidx.wear.compose:compose-material3:1.0.0-alpha25")
  ...  
}
Enter fullscreen mode Exit fullscreen mode

The library version at the time of writing is 1.0.0-alpha25.

Inside the build.gradle.kts file in the wearos app module, replace the previous wear compose material dependency androidx.wear.compose:compose-material with the above one. If youre using version catalogs, apply the adjustments in the respective gradle/libs.version.toml file as well.

Next, clean and rebuild the project, at this moment, the errors related to the replaced wear compose material library starts to show up.

Adjusting the MaterialTheme

So far so good, now, we're gonna fix the material theme properties (colors, typography, theme composable) using the new material3 classes for wearos.

Keep in mind that we're using an alpha version of the Android Wear Compose Material 3 library, so, the foundations of the library can be changed in the future.

Part 01: Color schemes

Firstly, the material 3 colors are different from previous material color system, so, in the Color.kt file, we see the contents like this:

/* Color.kt */
import androidx.compose.ui.graphics.Color
import androidx.wear.compose.material.Colors

internal val wearColorPalette: Colors = Colors(
  primary = Color(0xFFAECBFA),
  primaryVariant = Color(0xFF8AB4F8),
  secondary = Color(0xFFFDE293),
  secondaryVariant = Color(0xFF594F33),
  background = Color.Black,
  surface = Color(0xFF303133),
  error = Color(0xFFEE675C),
  onPrimary = Color(0xFF303133),
  onSecondary = Color(0xFF303133),
  onBackground = Color.White,
  onSurface = Color.White,
  onSurfaceVariant = Color(0xFFDADCE0),
  onError = Color(0xFF000000)
)
Enter fullscreen mode Exit fullscreen mode

In this case, we change the Colors variable with the following:

/* Color.kt */
import androidx.compose.ui.graphics.Color
import androidx.wear.compose.material3.ColorScheme

internal val wearColorPalette = ColorScheme(
  primary = Color(0xFF1F3701),
  primaryDim = Color(0xFF1F3701),
  primaryContainer = Color(0xFFCDEDA3),
  onPrimary = Color(0xFF354E16),
  onPrimaryContainer = Color(0xFFBFCBAD),
  secondary = Color(0xFF2A331E),
  secondaryDim = Color(0xFF2A331E),
  secondaryContainer = Color(0xFFDCE7C8),
  onSecondary = Color(0xFF404A33),
  onSecondaryContainer = Color(0xFFA0D0CB),
  tertiary = Color(0xFF003735),
  tertiaryDim = Color(0xFF003735),
  tertiaryContainer = Color(0xFFBCECE7),
  onTertiary = Color(0xFF1F4E4B),
  onTertiaryContainer = Color(0xFFFFB4AB),
  onSurface = Color(0xFF44483D),
  onSurfaceVariant = Color(0xFF8F9285),
  surfaceContainerLow = Color(0xFF1E201A),
  surfaceContainer = Color(0xFF282B24),
  surfaceContainerHigh = Color(0xFF33362E),
  outline = Color(0xFF44483D),
  outlineVariant = Color(0xFF000000),
  background = Color(0xFF12140E),
  onBackground = Color(0xFFE2E3D8),
  error = Color(0xFF690005),
  onError = Color(0xFF93000A),
  errorContainer = Color(0xFFFFDAD6),
  onErrorContainer = Color(0xFFE2E3D8),
)
Enter fullscreen mode Exit fullscreen mode

When using ColorScheme class, the attributes are quite similar to the m3 color available in the official m3 website.

For the color selection process, we refer to the material3 theme builder website. When picking the colors and fonts, and finally exporting the theme (in this scenario, export the compose theme), inside the exported theme it exists the Color.kt file.

Check the exported theme, open the Color.kt file, check the color pallete for light and dark theme, alog with the dynamic color contrast color palette, in it, you can find the dark color palette.

In this topic, the color palette for wearos takes the dark theme and not the light theme (not recommended, by the way), so, you use the dark colors pallete (os the dynamic color contrast color palettes) for initializing the color attributes in the ColorScheme class, with those attributes, the color palette.

After creating the color scheme for wearos, you can change the colors, but, keep in mind the material 3 color system definitions when doing so.

Part 02: Typography

In WearOS apps, there is a recommendation in the official ui design guide for using the default typography, which includes the Roboto font and the default settings (weight, size, style, etc.).

Now, let's change the typography for wearos app module using the m3 new Typography class.

/* Type.kt */

/* NOTE: New import, the old one is:<br> 
 * import androidx.wear.compose.material.Typography 
 */
import androidx.wear.compose.material3.Typography

// Set of Material typography styles to start with
val appTypography = Typography(...)
Enter fullscreen mode Exit fullscreen mode

In this topic, the textstyles for the Typography class are very different, for reference, lets see the following table:

M2 Typography Text styles M3 Typography Text styles
display1
display2
display3
title1
title2
title3
body1
body2
button
caption1
caption2
caption3
displayLarge
displayMedium
displaySmall
titleLarge
titleMedium
titleSmall
labelLarge
labelMedium
labelSmall
bodyLarge
bodyMedium
bodySmall
bodyExtraSmall
numeralExtraLarge
numeralLarge
numeralMedium
numeralSmall
numeralExtraSmall

The typography attributes / text styles are defined in a similar way to the official material 3 documentation, so, after changing the class, you can make the customizations that you want for default font family, sizes, etc.

NOTE: At the time of writing this, I am not aware of the numeral TextStyle and where to use it in composables, so we will keep an eye out for future updates to the Android Wear Compose Material 3 library.

Part 03: Shapes

Following with the material 3 Shapes for WearOS, they have similar recommendations and default settings as the previous section: For shapes, the official documentation generally recommend using the default Material Wear shapes which are optimized for round and non-round devices.

Now, let's change the shapes configuration for wearos app module using the m3 new Shapes class, if it doesn not exist, create the Shape.kt file.

/* Shape.kt */

/* NOTE: New import, the old one is:<br> 
 * import androidx.wear.compose.material.Shapes 
 */
import androidx.wear.compose.material3.Shapes

// Set of Material typography styles to start with
val appShapes = Shapes(...)
Enter fullscreen mode Exit fullscreen mode

The new Shapes class have added 2 more shape configurations, for reference, lets check the following table:

M2 Shapes M3 Shapes
small
medium
large
extraSmall
small
medium
large
extraLarge

You can customize the Shapes configuration for any of the listed shape sizes, but, keep in mind the material 3 color system definitions when doing so.

Part 04: Theme Composable

Now, let's glue the previous settings into the MaterialTheme composable function, in this topic, we do the following:

1- Fix the import, so we call MaterialTheme from material3 package.
2- Check that the colorScheme, typoghaphy (and shapes, if you did a customization of shapes) are compatible.

After this, the results is described in the following snippet:

/* Theme.kt */

import androidx.compose.runtime.Composable
import androidx.wear.compose.material3.MaterialTheme

@Composable
WearosTheme(
  content: @Composable () -> Unit
) {
  MaterialTheme(
    colorScheme = wearColorPalette,
    typography = appTypography,
    /* For shapes, we generally recommend using the default 
     * Material Wear shapes which are optimized for round 
     * and non-round devices.
     */
    shapes = appShapes,
    content = content,
  )    
}

Enter fullscreen mode Exit fullscreen mode

After doing this, let's clean and rebuild the project, since here we are ding the migration in a newly created wearos project, the error could be found in the MainActivity class and they are related to some imports and classes, so, let's fix them in the next section.

Fixing the errors in MainActivity class

Inside the mainActivity class, the following errors appeared:

a. Fix the imports related to androidx.wear.compose.material package:

import androidx.wear.compose.material3.MaterialTheme
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.TimeText
Enter fullscreen mode Exit fullscreen mode

b. Fix the usage of MaterialTheme.colors to MaterialTheme.colorScheme:

MaterialTheme.colors.background -> MaterialTheme.colorScheme.background
MaterialTheme.colors.primary -> MaterialTheme.colorScheme.primary
Enter fullscreen mode Exit fullscreen mode

c. Fix the TimeText composable invocation, inside the WearApp composable function body, here, we adjust the WearApp composable:

/* MainActivity.kt */
@Composable
fun WearApp(greetingName: String) {
  MyApplicationTheme {
    Box(
      modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background),
      contentAlignment = Alignment.Center
    ) {
      TimeText { time() }
      Greeting(greetingName = greetingName)
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

¿What happened in TimeText composable?

The mentioned composable has been upgraded, you can check the information from the composables.com website.

The complete MainActivity class looks like this:

/* MainActivity.kt */

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.wear.compose.material3.MaterialTheme
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.TimeText
import androidx.wear.tooling.preview.devices.WearDevices

class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    installSplashScreen()
    super.onCreate(savedInstanceState)
    setTheme(android.R.style.Theme_DeviceDefault)
    setContent {
      WearApp("Android")
    }
  }
}

@Composable
fun WearApp(greetingName: String) {
  MyApplicationTheme {
    Box(
      modifier = Modifier.fillMaxSize()
        .background(MaterialTheme.colorScheme.background),
      contentAlignment = Alignment.Center
    ) {
      TimeText { time() }
      Greeting(greetingName = greetingName)
    }
  }
}

@Composable
fun Greeting(greetingName: String) {
  Text(
    modifier = Modifier.fillMaxWidth(),
    textAlign = TextAlign.Center,
    color = MaterialTheme.colorScheme.primary,
    text = stringResource(R.string.hello_world, greetingName)
  )
}

@Preview(device = WearDevices.SMALL_ROUND, showSystemUi = true)
@Composable
fun DefaultPreview() {
  WearApp("Preview Android")
}
Enter fullscreen mode Exit fullscreen mode

With this, the next step is reabuild the project, there will be no errors at this point, so, from here, you can test the wearos app in the emulator or device.

Wearos sample app running in emulator

Conclusions

In this 'first steps' blog post, we learned to apply the Android Wear Compose Material 3 library, as a first glance, we found similar configs for the color schemes, typography, shapes and theme composable function, but, there are more changes, like the TimeText composable, that we could apply while using the library.

Keep in mind that the library is in alpha state, and, while so, there will be changes inside it, which can affect the usage of the composables/classes/values described here.

I hope you find this informative and useful and that at some point you can follow these steps in your Android applications, in order to apply a good migration to material 3 when developing Wearos apps.

Thanks for reading, happy coding! 😊

Top comments (0)