Engineering

06 October, 2020

Android Jetpack Compose — Navigation

If you’re an Android developer you’ve probably heard about Compose already. It’s everywhere, and it’s nice to see the Android community so excited about it.

António Valente

Software Engineer

Android Jetpack Compose — Navigation - Coletiv blog

If you’re an Android developer you’ve probably heard about Compose already. It’s everywhere, and it’s nice to see the Android community so excited about it. For the ones that haven’t heard about it already, Compose is Android’s modern toolkit for building native UI that hopes to simplify and accelerate UI development on Android. It’s all in Kotlin so you can forget about writing UI code on XML, and that alone is something to be excited for 😄. Check the official page and try it out if you haven’t already.

But enough of chit-chat and let’s get on the topic because that’s what you’re here for.

How to handle navigation on Compose

As you might know already, there’s no official way of doing navigation with Compose, if you want to go full Compose you need to handle it yourself and that’s a pain 🔨.

You can’t do an app with Compose without using a least one Activity (at least for now) so let’s use this to our advantage and use the Navigation jetpack component, it has a lot of nice features and is the current official recommended way of handling navigation on Android apps. Let’s check how we can do this.

Using the Navigation component

Telling you how to get started with the Navigation component is out of the scope of this article but you can follow the official getting started tutorial.

I’m assuming that you have your MainActivity setup alongside a start destination fragment.

The layout file of your MainActivity should look like this:

<?xml version="1.0" encoding="utf-8"?> <androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/host_fragment_container" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" tools:context=".ui.screens.MainActivity" />

That’s the only layout file we need. I promise 😅.

You can delete your fragment layout file and update the code to this:

class SomeFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? = ComposeView(requireContext()).apply { setContent { AwesomeComposable() } } @Composable fun AwesomeComposable() { ... } }

This is where the magic happens. We’re telling our fragment that we want to use a ComposeView and we’re calling setContent to set our Compose UI. No need for layout files or other views 👍.

Then you just need to create more fragments like this one and add them to your nav_graph.xml file as destinations.

Now you should be able to navigate to those destinations inside your composable functions by calling:

findNavController().navigate(R.id.your_action_here)

You can improve this further by creating a base fragment class like this:

abstract class ComposeFragment : Fragment() { @Composable abstract fun ComposeContent() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? = ComposeView(requireContext()).apply { setContent { ComposeContent() } } }

And use it on your fragments like this:

class SomeFragment : ComposeFragment() { @Composable override fun ComposeContent() { // your compose layout } }

Neat! Now you can forget that you’re using fragments and focus on Compose to write some beautiful UI 🌠. Go crazy!

What if I want to go full Compose?

For the time being, you have 2 options that I’m aware of:

  • You can try to use the compose-router library that adds routing functionality to Jetpack Compose.

  • Write your navigation system. Be sure to check Jetpack Compose Samples for some examples on how to do this.

But I think that the best option at this time is to use the mature Navigation component like suggested here and wait until there’s an official way of handling navigation on Compose. Sure, you’ll be using fragments with ComposeView (which seems to be old/outdated comparing to Compose) but you’ll always have a MainActivity somewhere in your project to set the content of your composable functions, so might as well take some advantage of it.

Wouldn’t it be nice to have a main() function that would allow us to write our compose code right away? No Activity or Fragment needed? Let’s keep dreaming 😄!

Software Development

Android

Compose

Jetpack

Navigation

Join our newsletter

Be part of our community and stay up to date with the latest blog posts.

Subscribe

Join our newsletter

Be part of our community and stay up to date with the latest blog posts.

Subscribe

You might also like...

Go back to blogNext
How to support a list of uploads as input with Absinthe GraphQL

Engineering

26 July, 2022

How to support a list of uploads as input with Absinthe GraphQL

As you might guess, in our day-to-day, we write GraphQL queries and mutations for Phoenix applications using Absinthe to be able to create, read, update and delete records.

Nuno Marinho

Software Engineer

Flutter Navigator 2.0 Made Easy with Auto Router - Coletiv Blog

Engineering

04 January, 2022

Flutter Navigator 2.0 Made Easy with Auto Router

If you are a Flutter developer you might have heard about or even tried the “new” way of navigating with Navigator 2.0, which might be one of the most controversial APIs I have seen.

António Valente

Software Engineer

Enabling PostgreSQL cron jobs on AWS RDS - Coletiv Blog

Engineering

04 November, 2021

Enabling PostgreSQL cron jobs on AWS RDS

A database cron job is a process for scheduling a procedure or command on your database to automate repetitive tasks. By default, cron jobs are disabled on PostgreSQL instances. Here is how you can enable them on Amazon Web Services (AWS) RDS console.

Nuno Marinho

Software Engineer

Go back to blogNext