Bites of Compose 5

Learn Jetpack Compose one bite at a time

Guowei Lv

2 minute read

Let’s talk about Modifier.

Situation 1

What is the simplest Modifier?



What is it? a class? an object?

It is a companion object, which implements the Modifier interface.

companion object : Modifier {
    override fun <R> foldIn(initial: R, operation: (R, Element) -> R): R = initial
    override fun <R> foldOut(initial: R, operation: (Element, R) -> R): R = initial
    override fun any(predicate: (Element) -> Boolean): Boolean = false
    override fun all(predicate: (Element) -> Boolean): Boolean = true
    override infix fun then(other: Modifier): Modifier = other
    override fun toString() = "Modifier"

The formal version is Modifier.Companion, but can be shortened as Modifier.

I know, this can be confusing, but let’s write a simpler example to understand it step by step.

First we need to understand that the so called companion object, is just a kind of global object attached to a class or interface itself, this is similar to the static members of a class in Java.

For example:

class Person {
    companion object {
        const val TAG = "person"
        fun talk() = print("I'm talking...")

The “Person class” has a TAG property and a “static function” talk(). And to access this companion object we can just write Person.Companion or simply Person.


Also, the companion object can implement interface.

interface Runnable {
    fun run()

class Person {
    companion object : Runnable {
        const val TAG = "person"
        fun talk() = print("I'm talking...")
        override fun run() {

And not only classes, but interfaces can also have companion object. And if its companion object implements itself…

interface Car {
    fun drive()
    fun stop()

    companion object : Car {
        override fun drive() {

        override fun stop() {

This is exactly how Modifer is doing.

Situation 2

What does this mean?

Box(modifer: Modifier = Modifier)


Passing in the most basic Modifier object as default parameter.

Situation 3

Is this companion object Modifier used anywhere else?


Yes, it is also used when you do something like:


Let’s look into the source code:

fun Modifier.background(
    color: Color,
    shape: Shape = RectangleShape
) = this.then(
        color = color,
        shape = shape,
        inspectorInfo = debugInspectorInfo {
            name = "background"
            value = color
            properties["color"] = color
            properties["shape"] = shape

As you can see, background() is an extension function of the companion object Modifier (not the interface Modifier!).

comments powered by Disqus