Installing Enro
Add the Gradle Dependencies
The first step in installing Enro is to add the Gradle dependencies to your project. These should be added to your application module, as well as any modules that will use Enro.
dependencies {
implementation("dev.enro:enro:<latest_version>")
ksp("dev.enro:enro-processor:<latest_version>") // optional but highly recommended
// kapt("dev.enro:enro-processor:<latest_version>") - if you're using KAPT not KSP
testImplementation("dev.enro:enro-test:<latest_version>") // optional test extensions
}
Add Enro to your Application class
Enro needs to be added to the Application class used by your Application. This is also where you can apply custom configuration to Enro, if your application requires this.
Show step-by-step guide
0. An application class without Enro installed
class ExampleApplication : Application {
// ...
}
1. Add the NavigationApplication
interface
class ExampleApplication : Application, NavigationApplication {
// ...
}
2. Override the navigationController
property
class ExampleApplication : Application, NavigationApplication {
override val navigationController = createNavigationController { }
// ...
}
In the example above we’re passing an empty block to the createNavigationController
function, but this block is used to provide configuration to Enro. In a simple application that uses annotation processing, you may not need to provide any configuration, but it’s useful to be aware that this is what the block is used for. Please see Configuring Enro for more information.
3. Add the @NavigationComponent
annotation to your Application (if using kapt/annotation processing)
@NavigationComponent
class ExampleApplication : Application, NavigationApplication {
override val navigationController = createNavigationController { }
// ...
}
If you are using annotation processing (which is optional, but recommended), you are required to annotate your Application class with @NavigationComponent
so that the annotation processor has a hook to generate and provide configuration.
If you are not using annotation processing, you won’t need to add this annotation. Instead, you’ll need to provide your Application’s configuration within the createNavigationController
block. Please see Configuring Enro for more information.
Add Enro to an Activity
Once you’ve added Enro to your Application, it’s likely that you’ll want to add a Navigation Container to an Activity. This isn’t necessary, as navigation using Enro will work even without a Navigation Container, but it is recommended. The exact configuration of the Navigation Container will depend on your needs, and the examples below will deal with a reasonably simple case, so if you need more information on how to configure a Navigation Container, please see the Navigation Container documentation.
What is a Navigation Container?
A Navigation Container is a ViewGroup or Composable that maintains a backstack and displays the active Navigation Destination for that backstack. If you’re familiar with Fragments, think of it as the FrameLayout
that holds the Fragments. If you’re more familiar with Compose, think of it as a Box
that holds some child content (the active destination). For more information, please see the Navigation Container documentation.
Adding a Navigation Container for Fragments and Composables
If your application has Navigation Destinations that are a mix of Fragments and Composables, your top level Navigation Container should be a View based Navigation Container, as this will accept both Fragment and Composable destinations.
Show step-by-step guide
0. An Activity without a Navigation Container
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
1. Add a FrameLayout to your Activity’s layout file
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/exampleNavigationContainer"
/>
<!-- ... -->
</androidx.constraintlayout.widget.ConstraintLayout>
2. Add a Navigation Container property to your Activity
class MainActivity : AppCompatActivity() {
private val exampleContainer by navigationContainer(
containerId = R.id.exampleNavigationContainer,
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
3. Configure the Navigation Container
The Navigation Container that we’ve defined above will start off with nothing in it, and it will allow any Navigation Destination to be pushed into it. Below is an example of a configured Navigation Container that will initially show the Navigation Destination for a particular Navigation Key, and will finish
the Activity if the Navigation Container is ever about to become empty. This isn’t always the behavior that you will want for a Navigation Container, but it is a reasonably common way to set up an Activity’s root Navigation Container. For more information, please see the Navigation Container documentation.
class MainActivity : AppCompatActivity() {
private val exampleContainer by navigationContainer(
containerId = R.id.exampleNavigationContainer,
root = { ExampleRootNavigationKey(/* ... */) },
emptyBehavior = EmptyBehavior.CloseParent,
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Adding a Navigation Container for Composables only
If your application only has Composable destinations, you can choose to use a View based Navigation Container (as these support Composable destinations too), but you may want to consider directly using a Composable NavigationContainer.
Show step-by-step guide
0. A Composable Activity without a Navigation Container
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// ...
}
}
}
1. Add a Navigation Container variable
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val container = rememberNavigationContainer()
// ...
}
}
}
2. Render the Navigation Container
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val container = rememberNavigationContainer()
Box(modifier = Modifier.fillMaxSize()) {
container.Render()
}
// ...
}
}
}
3. Configure the Navigation Container
The Navigation Container that we’ve defined above will start off with nothing in it, and it will allow any Navigation Destination to be pushed into it. Below is an example of a configured Navigation Container that will initially show the Navigation Destination for a particular Navigation Key, and will finish
the Activity if the Navigation Container is ever about to become empty. This isn’t always the behavior that you will want for a Navigation Container, but it is a reasonably common way to set up an Activity’s root Navigation Container. For more information, please see the Navigation Container documentation.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val container = rememberNavigationContainer(
root = ExampleRootNavigationKey(/* ... */),
emptyBehavior = EmptyBehavior.CloseParent,
)
Box(modifier = Modifier.fillMaxSize()) {
container.Render()
}
// ...
}
}
}