Exploring Jetpack Compose: Floating Action Button

E

The floating action button is an important component in mobile applications – allowing us to showcase primary actions for our users to carry out. Within Jetpack Compose we can create Floating Action Buttons in a variety of ways, with the approaches giving us greater flexibility than how we would currently create FABs within XML layouts.

When it comes to the Floating Action Button, there are three methods available that we can use to compose the component – each of these provides us with a different way of building our FAB. Let’s take a look at each of these methods and how we can use them within our codebase.


Floating Action Button with Icon

In some cases we will want to display a floating action button with an icon. For this, the following composable function is available:

@Composable
fun FloatingActionButton(
    icon: Image,
    modifier: Modifier = Modifier.None,
    onClick: (() -> Unit)? = null,
    shape: Shape = CircleShape,
    color: Color = MaterialTheme.colors().primary,
    elevation: Dp = 6.dp
)

As we can see above, there are a collection of attributes that we can pass in which will depict how our FAB is going to be displayed.

  • icon – the icon to be displayed on the button. This is required when using the function.
  • modifier – the modifier to be applied to the button. If not provided, no modifiers will be applied to the component.
  • onClick – a lambda used for when the button is clicked. If not provided, the button will not respond to click events.
  • shape – the shape to be used when drawing the component. This will default to a circular shape if not provided.
  • color – the background color of the component. This will default to the primary theme of your application.
  • elevation – the Dp value defining the level of elevation to be applied to the component. By default elevation will be set to 6dp

For example, we can construct a FAB by just providing an icon like so:

FloatingActionButton(
    icon = imageResource(id = R.drawable.ic_share) 
)

Here we provide the only required argument for the composable function, the icon. This gives us FAB that uses default properties for all of the other attributes, along with the provided icon to represent out primary action.

We’ll need to be able to provide a click handler in most cases. As mentioned above, this defaults to null if not provided so we’ll pass in a handler to trigger the desired side-effect of a click on our view:

FloatingActionButton(
    icon = imageResource(id = R.drawable.ic_share),
    onClick = {
        // Handle onClick event
    }
)

This function for the FAB also allows us to pass in a reference to a modifier. We’ve already covered what modifiers are and some of the ones that are available, but for examples sake let’s provide a DrawBorder modifier:

FloatingActionButton(
    icon = imageResource(id = R.drawable.ic_share),
    modifier = DrawBorder(
        border = Border(1.dp, Color.White),
        shape = CircleShape
    )
)

We can use any of the available modifiers for the FAB, with DrawBorder being just one of them. For now, let’s remove our modifier and use the shape argument to change the shape appearance of our button. Here we’ll pass in the RectangleShape reference to use a Rectangle for our FAB instead of the default Circle:

FloatingActionButton(
    icon = imageResource(id = R.drawable.ic_share),
    shape = RectangleShape
)

Whilst the shape represents a big part of how our FAB looks, we can also change the color of the FAB by providing a Color reference for the color argument of our function: 

FloatingActionButton(
    icon = imageResource(id = R.drawable.ic_share),
    color = Color.Cyan
)

Finally, we may want to alter the elevation of our button using the elevation argument, if not provided then this will default to 6dp.

FloatingActionButton(
    icon = imageResource(id = R.drawable.ic_share),
    elevation = 10.dp
)

With the above in place we can construct a simple Floating Action button by at least providing an icon for the button, using the other available attributes to style the button for our needs.


Floating Action Button with Icon and Text

Whilst the above approach allows us to implement a simple FAB, in some cases we may wish to extend this further and provide additional context within our button, such as text.  When these are our requirements we can use the second composable function to build a FAB.

@Composable
fun FloatingActionButton(
    text: String,
    modifier: Modifier = Modifier.None,
    icon: Image? = null,
    textStyle: TextStyle? = null,
    onClick: (() -> Unit)? = null,
    color: Color = MaterialTheme.colors().primary,
    elevation: Dp = 6.dp
)

As we can see above, there are a collection of attributes that we can pass in which will depict how our FAB is going to be displayed.

  • text – the textual content to be displayed within the button. This is required when using the function.
  • modifier – the modifier to be applied to the button. If not provided, no modifiers will be applied to the component.
  • icon – the icon to be displayed on the button.
  • textStyle – stylistic properties to be applied to the provided text
  • onClick – a lambda used for when the button is clicked. If not provided, the button will not respond to click events.
  • color – the background color of the component. This will default to the primary theme of your application.
  • elevation – the Dp value defining the level of elevation to be applied to the component. By default elevation will be set to 6dp

As you may have noticed, a lot of these attributes are very similar as to the ones we explored in the previous composable function for the FAB. Because of this, we’ll focus on covering the ones unique to this specific function. One important thing to notice here is that we can no longer set the shape of the FAB – because this method is used for building FABs that contain text, a pill shape is always used to account for the textual content displayed within the button. In terms of additions, the main one here is that we can pass a reference to a string value, this being the only required attribute.

FloatingActionButton(
    text = "Share"
)

This method still allows us to provide an icon if we wish to display one within the button and alongside our text.

FloatingActionButton(
    text = "Share",
    icon = imageResource(id = R.drawable.ic_share)
)

With our icon added, it looks a little odd how our icon and text are displayed using different colours. Here we can use the textStyle property to change the appearance of our text. We’ve already covered this class in depth, so here we’ll just use it to change the color of our text:

FloatingActionButton(
    text = "Share",
    icon = imageResource(id = R.drawable.ic_share),
    textStyle = TextStyle(color = Color.Black)
)

With the above in place we are able construct a Floating Action button that is using textual content either by itself or alongside a supporting icon, using the other available attributes to style the button and its supporting content for our needs.


Floating Action Button with Children

Whilst both of the above approaches allow us to implement FABs that contain icons, text or even both – we might need something that allows for further customisation than passing in icon / string references. If this is the case then we can use the third FAB composable function that allows for us to pass in a composable child to be used for the content of our button.

@Composable
fun FloatingActionButton(
    modifier: Modifier = Modifier.None,
    onClick: (() -> Unit)? = null,
    minSize: Dp = FabSize,
    shape: Shape = CircleShape,
    color: Color = MaterialTheme.colors().primary,
    elevation: Dp = 6.dp,
    children: @Composable() () -> Unit
)

As we can see above, there are a collection of attributes that we can pass in which will depict how our FAB is going to be displayed.

  • modifier – the modifier to be applied to the button. If not provided, no modifiers will be applied to the component.
  • onClick – a lambda used for when the button is clicked. If not provided, the button will not respond to click events.
  • minSize – the minimum size of the FAB, in the form of a DP value. If not provided then this will default to 56dp.
  • shape – the shape to be used when drawing the component. This will default to a circular shape if not provided.
  • color – the background color of the component. This will default to the primary theme of your application.
  • elevation – the Dp value defining the level of elevation to be applied to the component. By default elevation will be set to 6dp.
  • children – a composable child used for the content of the FAB. This is required when using this composable function.

As you may have noticed, a lot of these attributes are very similar as to the ones we explored in the previous composable function for the FAB. Because of this, we’ll focus on covering the ones unique to this specific function. One important thing to notice here is that we can no longer set either the icon or text used within the FAB – instead with this method we pass a composable child which contains the content of the button.

As most of the above attributes are the same as the other available buttons, let’s focus on the core difference here. Being able to pass a composable child via the children argument is a powerful feature – maybe we have a custom composable, or wish to display something that the previous FAB functions do not cater for. For example sake, let’s pass a column with two nested text components:

FloatingActionButton(
    shape = RectangleShape,
    children = {
        Column {
            Text("One")
            Text("Two")
        }
    }
)

Whilst the above is not likely something that you might not implement (if so, then maybe not often), this shows how much flexibility this function offers us when we want to build a FAB.


With the examples displayed here we have the knowledge to be able to create Floating Action Buttons within Jetpack Compose, along with the ability to customise them to suit the needs of our designs. If you’re looking to start exploring the FAB within Jetpack Compose or have already done so, I’d love to hear any thoughts or questions that you may have on the component!

[twitter-follow screen_name=’hitherejoe’ show_count=’yes’]

About the author

hitherejoe

Add Comment