Clean Empty Jetpack Compose App Template
Tags: android, beginners, kotlin, jetpackcompose
Published: 2022-05-28 00:56:39

**Simple and clean empty Jetpack Compose app example which doesn't have themes.xml and colors.xml.**

For pure Jetpack Compose app, technically we don't need the `themes.xml` and `colors.xml` anymore, which are meant for Android View system.

However, I have seen a lot of code out there still have these `themes.xml` and `colors.xml` defined. Personally, I would remove them to avoid duplication or confusion.

## 1. Remove themes.xml and colors.xml

Removing `themes.xml` and `colors.xml` can cause compilation error due to it is still being referenced from `AndroidManifest.xml`. You need to modify the `AndroidManifest.xml`


- Remove `android:theme="@style/Theme.EmptyComposeApp"` in both `<application>` and`<activity>`

```xml
<application
	...
	android:theme="@style/Theme.EmptyComposeApp">
	<activity
		...
		android:theme="@style/Theme.EmptyComposeApp">
		...
	</activity>
</application>
```

- Replace with `android:theme="@android:style/Theme.Material.Light.NoActionBar"` in `<application>` which is the parent style in your `themes.xml`.

```xml
<application
	...
	android:theme="@android:style/Theme.Material.Light.NoActionBar">
    ...
</application>
```

> The creates an app without the top action bar. The top action bar can be created using `Scaffold` composable function. See this [Add Top App Bar Example](https://vtsen.hashnode.dev/convert-recycleview-to-lazycolumn-jetpack-compose#heading-4-add-top-app-bar) in this Simple LazyColumn App.

I did try to not adding this `android:theme="@android:style/Theme.Material.Light.NoActionBar"` but the `ComponentActivity()` creates the top action bar by default which I have no idea to get rid of it using Jetpack Compose.

## 2. Set Status Bar Color with Compose
 
Well, the app works, but the default purple color in the status bar is gone.

If you look at the original `themes.xml`, it set the status bar color there. 
```xml
<resources>
    <style name="Theme.EmptyComposeApp" parent="android:Theme.Material.Light.NoActionBar">
        <item name="android:statusBarColor">@color/purple_700</item>
    </style>
</resources>
```
Since this has been removed, we need to implement this in Jetpack Compose. To do that, we need to use the [System UI Controller](https://google.github.io/accompanist/systemuicontroller/) from Accompanist.

- Add `com.google.accompanist:accompanist-systemuicontroller` library:

```
dependencies {
    ...
    implementation "com.google.accompanist:accompanist-systemuicontroller:0.24.1-alpha"
    ...
}
```

- In `ui\Theme\Theme.kt`, add this to set `purple_700` color which is also the `primaryVariant` color

```kotlin
val systemUiController = rememberSystemUiController()
systemUiController.setStatusBarColor(
	color = colors.primaryVariant
)
```

- The complete code looks like this:

```kotlin
fun EmptyComposeAppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

    val systemUiController = rememberSystemUiController()
    systemUiController.setStatusBarColor(
        color = colors.primaryVariant
    )

    MaterialTheme(
        colors = colors,
        typography = Typography,
        shapes = Shapes,
        content = content
    )
}
```

The template project from Android Studio doesn't set the navigation bar color. Thus, we're not setting them here in the example above. However, we usually want to set the same color for both the navigation and status bars. In that case, you can use `systemUiController.setSystemBarsColor()`:

```kotlin
val systemUiController = rememberSystemUiController()
systemUiController.setSystemBarsColor(
	color = colors.primaryVariant
)
```

> Since I want to use this example as my own template project. I'm going to change it to use `systemUiController.setSystemBarsColor()` in this app example.

## 3\. Add Advertising ID Permission

The latest requirement for your app targeting SDK 33 is, you must declare this advertising ID (`com.google.android.gms.permission.AD_ID`) user permission in your manifest file.

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
    ...
</manifest>
```

## Issues
### Preview is Not Rendering
There is a bug the preview is not working when the System UI controller is used.  See issue tracker [here](https://github.com/google/accompanist/issues/918).

```
java.lang.IllegalArgumentException: The Compose View must be hosted in an Activity with a Window!
```

The workaround is you need to disable the System UI controller in preview by passing in the `useSystemUIController` parameter.

In `Theme.kt`:
```kotlin
@Composable  
fun EmptyComposeAppTheme(  
  ...  
  useSystemUIController: Boolean = true,  
  ...
) {  
    ...
    if (useSystemUIController) {  
        val systemUiController = rememberSystemUiController()  
        systemUiController.setStatusBarColor(  
            color = colors.primaryVariant)  
    }  
    ...
}
```
In `MainActivity.kt`:
```kotlin
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    EmptyComposeAppTheme(useSystemUIController = false) {
        ...
    }
}
```

### Clean Task is No Longer Needed

> **\[Updated - Jan 11, 2023\]**: I found out that we no longer need to register the clean task in your build.gradle file as Gradle has already been implemented by default.

The following task can be removed from **build.gradle** file.

```kotlin
tasks {
    register("clean", Delete::class) {
        delete(rootProject.buildDir)
    }
}
```

## Summary
Now I only have `strings.xml` in my resource folder. Cool, isn't it?

![Clean_Empty_Jetpack_Compose_App_01.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1643599212610/ZJEI-5z9l.png)

I will probably also use this as starting point of any Jetpack Compose project. This diff [here](https://github.com/vinchamp77/Demo_CleanEmptyCompose/commit/4f86b00ebfa04a91e830f312cfd6c442d23e885a) shows the changes needed to change the package and project names.

> **[Updated - 18 July, 2022]:** If you rename the package and etc. from the template app, you're maybe getting the compilation error (usually is related to string resources). In that case, you can [invalidate caches](https://vtsen.hashnode.dev/deep-clean-your-android-studio-to-fix-weird-issues#heading-2-invalidate-caches). I only turn on the **Clear VCS Log caches and indexes** and it works for me.

## Source Code
GitHub Repository:  [Demo_CleanEmptyCompose](https://github.com/vinchamp77/Demo_CleanEmptyCompose)

---

*Originally published at [https://vtsen.hashnode.dev](https://vtsen.hashnode.dev/clean-empty-jetpack-compose-app-template)*.