How to Get up and Running with Turbo Android Part 2 - Feel More Native
Tags: turbo, hotwire, android, native
Published: 2023-05-23 14:04:48

---
title: How to Get up and Running with Turbo Android Part 2 - Feel More Native
published: true
date: 2023-05-19 00:00:00 UTC
tags: turbo, hotwire, android, native
canonical_url: https://williamkennedy.ninja/android/2023/05/19/turbo-android-part-2-feel-more-native/
---

So far, we’ve covered getting up and running with [Turbo Android](/android/2023/05/10/up-and-running-with-turbo-android-part-1/). Now we can move on to the fun part of Turbo Android, which is about making it feel more native. Compared to [Turbo-ios](http://localhost:4000/ios/2022/09/12/how-to-render-a-native-home-screen-with-turbo-ios/), Turbo Android has a lot built into the framework and can easily route different endpoints.

## Getting Setup with Modals

You may have noticed that the Android app doesn’t feel very native. Instead, it feels like a webpage inside an app’s skin. Luckily, we can add some quick changes utilising [Turbo Fragments](https://github.com/hotwired/turbo-android/tree/main/turbo/src/main/kotlin/dev/hotwire/turbo/fragments) found in the [Turbo-Android library](https://github.com/hotwired/turbo-android/tree/main/turbo/src/main/kotlin/dev/hotwire/turbo/fragments). By inheriting from these and updating out Path Configuration, we have routes display different Turbo Fragments.

For now, we will update our codebase so that every route that ends with `new` and `edit` will result in a modal popup like the one shown in this gif.

![alt text](https://williamkennedy.ninja/assets/images/posts/android/part_2/bottom_modal.gif "Rendering Modal")

### Update PathConfiguration

We created a [path configuration](https://github.com/hotwired/turbo-android/blob/main/docs/PATH-CONFIGURATION.md) file under assets/json in the previous tutorial. Let’s edit that and add a new rule.

```
{
  "patterns": [
    "/new$",
    "/edit$"
  ],
  "properties": {
    "context": "modal",
    "uri": "turbo://fragment/web/modal/sheet",
    "pull_to_refresh_enabled": false
  }
}

```

This is telling our Turbo Android app to use the class that’s annotated with `@TurboNavGraphDestination(uri = "turbo://fragment/web/modal/sheet")` for any route that ends in `new` or `edit`.

### Create the Fragment and add it

Now we need to create the fragment. Add a new Kotlin class and call it `WebBottomSheetFragment` and make sure to inherit from `TurboWebBottomSheetDialogFragment()`

```

import dev.hotwire.turbo.fragments.TurboWebBottomSheetDialogFragment
import dev.hotwire.turbo.nav.TurboNavGraphDestination

@TurboNavGraphDestination(uri = "turbo://fragment/web/modal/sheet")
class WebBottomSheetFragment : TurboWebBottomSheetDialogFragment() {}

```

We’re not done yet. We’ve to add it to the list of registered fragments in our `MainSessionNavHost`

```
class MainSessionNavHost : TurboSessionNavHostFragment() {
  ...

    override val registeredFragments: List<KClass<out Fragment>>
    get() = listOf(
        WebFragment::class,
        WebBottomSheetFragment::class,
        )
    ...
}

```

When we run the app and navigate to any route that ends in `new` or `edit`, we display a modal.

## Rendering a Native Screen

The exact process that we used to add a modal we can also use it to navigate to a native screen. Let’s navigate to a simple Hello World screen written with Jetpack Compose. Jetpack Compose is Google’s modern UI tool and is similar to SwiftUI.

There is a little setup involved if we use the modern approach to building Android tools. So let’s dive in step by step.

### Update build.gradle

We have to add the compose libraries to our app and ensure that it will compile Jetpack Compose.

```
android {
  ...
    buildFeatures {
      compose true
    }
  ...
}

dependencies {

  implementation 'androidx.compose.ui:ui:1.4.2'
    implementation 'androidx.compose.material:material:1.2.0'
    def composeBom = platform("androidx.compose:compose-bom:2023.03.00")
    implementation(composeBom)
    ....
}

```

Make sure to sync your changes.

Next, we update our Path Configuration to render specific routes with a native screen.

```
{
  "patterns": [
    "/hello_world"
  ],
  "properties": {
    "context": "default",
    "uri": "turbo://fragment/hello_world"
  }
},

```

Now we create the `HelloWorldFragment`, which inherits from `TurboFragment`

```
  @TurboNavGraphDestination(uri = "turbo://fragment/hello_world")
  class HelloWorldFragment : TurboFragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
      return ComposeView(requireContext()).apply {
        setContent {
          Hello()
        }
      }
    }

    @Composable
      fun Hello() {
        Column(
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
            ) {
          Text("Hello World")
        }
      }
  }

```

Finally, we add this fragment to the list of registered fragments:

```
class MainSessionNavHost : TurboSessionNavHostFragment() {
  ...

    override val registeredFragments: List<KClass<out Fragment>>
    get() = listOf(
        WebFragment::class,
        WebBottomSheetFragment::class,
        HelloWorldFragment::class 
        )
    ...
}

```

**\*NOTE: You may have to change your Kotlin version to 1.7.0 to compile. This can be changed in `build.grade(project)`**

Once we’ve run the app, we should be able to navigate to the `/hello\_world` route and voila:

![alt text](https://williamkennedy.ninja/assets/images/posts/android/part_2/native_screen.gif "Rendering native screen gif")

It’s pretty basic, but it’s enough to build on. In the next blog post, we will talk about the JavaScript bridge, and then we will talk about little improvements we can make to our Turbo app to make it even better.