Seeing your composable in shades of grey

Creating a greyscale modifier in Jetpack Compose and how to make complex composables look disabled.

Katie Barnett
ProAndroidDev

--

Photo by Rodion Kutsaiev on Unsplash

Recently, I needed to make a composable look disabled, my friendly design team wanted something quite complex turned to greyscale and made slightly transparent. And it had to be dynamic with changeable data, so I could not just use a drawable for when the composable was in disabled mode, and overlaying a grey box was just not going to cut it design wise.

My first thought was, filters to the rescue! Couldn’t I could apply a filter to the whole composable and be done with it? Unfortunately, there is no filter wrapper for a composable or filter modifier. But, it is a pretty easy thing to create yourself!

If you just want to convert a simple image to black and white you can of course use a colour filter with a colour matrix and set the saturation to zero.

This works so well for a photo:

Photo by Olesia 🇺🇦 Buyar on Unsplash

But if your composable involves more than just one photo, especially a more complex or dynamic layout, to acheive the same effect you would need to add logic in many places. For example, for a scene involving a background, photo and some text, the code becomes more complex:

This also means I need to define the exact colour in greyscale for my components. Which may not be possible or practical for dynamic data, especially if there are a range of possible colours.
Photo by Olesia 🇺🇦 Buyar on Unsplash

Creating a greyscale modifier

I have been recently having fun with creating custom modifiers, so I thought that a good way to apply a filter to an entire composable would be with a modifier.

Here we can create a custom drawing modifier, create the saturation matrix and filter and then apply that to the painting of the drawing layer in the canvas:

This has the added benefit of removing the saturation evenly so you can use this for dynamic content and colours and not have to manually convert each colour and maintain legibility.

For example, if we start with:

Then apply the modifier at the top level:

It will apply consistently to all the images, and still show the shade difference between the images that were in different colours.

Making composables look disabled

As I mentioned above, the original reason I wanted to turn my composables to greyscale was to make them look disabled so the user knows that they could not interact with them. Greyscale alone is not desirable, I needed to add in an alpha modifier. This can be combined into one modifier that can be reused throughout the codebase:

This looks much better and the code will be much easier to apply, even with conditional modifiers!

You can check out the full code and my other Jetpack Compose modifier experiments here:

The code used in this post was inspired by this Stack Overflow question & answers.

While you are at it, check out some other fun I have had with conditional Jetpack Compose Modifiers.

--

--