Jetpack Compose Tidbits: The first dance with JC - Learning the steps
Tags: android, beginners, tutorial, programming
Published: 2021-12-29 12:07:16

![A dancing female image by Gordon Johnson](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gt4syb8sjljkluxc9vhc.png)
<p style="text-align: center;"><sub><sup>Image by</sup></sub> <a href="https://pixabay.com/users/gdj-1086657/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=5437872"><sub><sup>Gordon Johnson</sup></sub></a> <sub><sup>from</sup></sub> <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=5437872"><sub><sup>Pixabay</sup></sub></a> </p>

---

With Android's fresh way of developing UI, there's little to no XML which was formerly the primary way of designing UI for Android apps. With [Jetpack Compose](https://developer.android.com/jetpack/compose/documentation), you just declare what you need for creating your UI by calling functions and Jetpack Compose handles the implementation. When you need your UI to reflect come changes with the user's data, the functions you created just get called again with the new data. 
Jetpack Compose comes with Android Jetpack, a collection of software components launched in 2018 that work to make developing Android apps easier and more efficient. Before JC, using views was the primary way of creating UI in Android, thus, many of the apps already existing are built with views, that is why Compose can exist in harmony with views so you can be sure that you don't need to throw away all your old code with views when starting out with Compose. Instead, you can make the shift to Compose in a way that suits you best. 
 
If you've ever programmed with Flutter, chances are, you're going to fit right in with Jetpack Compose since Compose comes with a reactive style of programming.

---

## Setting up the dance floor

To get started with Compose you must have [Android Studio Arctic Fox](https://developer.android.com/studio). 
After downloading Android Studio and successfully launching it, we can create a new compose project by clicking _New Project_,
![Android studio click new project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i1er12gced4fl7vee6tu.png)
 
And then click _Empty Compose Activity_ to start creating your Compose app, 
![Android Studio select empty compose activity](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/624tbm6ykzfxlxlpelm8.png)

A pop-up titled "Empty Compose Activity" appears, and we can go ahead to change our project's name to something more fitting: 
![create compose activity](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sos1vmz77cgor88odn38.png)

The save location is where your project will locally be stored on your machine, and the package name uniquely identifies your app. The value supplied for the save location will be slightly different depending on your choices when installing Android Studio, and although you can change it and the package name, it would be better to leave it as is since the explanation given from this point is done in accordance with these exact values. 

![create a  compose project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgf6xxwsnofxlqdq5n0r.png)

The process is smooth and free of hitches if your internet connection is enabled and stable. 
If you were unable to follow along with the above steps, you can visit [Android developer's official site](https://developer.android.com/jetpack/compose/setup) to see more info about the setup process.

## Getting to know your partner, JC
After Android Studio finishes setting up your project, you should have a file with the name `MainActivity.kt` automatically shown in the editor window (the space available in Android Studio where the details of files are seen and interacted with). 
You should also be able to see this sample bit of code:

```
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            FirstComposeAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}
```
<a href="#code_one">code snippet: 1.0</a>

This file belongs to the launching activity of your app called `MainActivity`. The class name also points to this. An activity, is the primary component of any android app that involves continuous interaction with the user. It serves as the entry point of your app in which you can let the user interact with your app. It, most commonly, shows UI as a single screen in the app. A more in-depth explanation can be found in the [Android docs](https://developer.android.com/reference/android/app/Activity). `MainActivity` is your launching activity because it was automatically set as so in the `AndroidManifest.xml` upon the creation of your project. `AndroidManifest.xml` is a [manifest file](https://developer.android.com/guide/topics/manifest/manifest-intro). It describes your app to Android systems, therefore, every app project you create must have it. To see what the manifest file looks like, go into the project window and double-click the manifests directory:
![android project window](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lad0jlmewi9v1sya4cqn.png)
 
This opens up the manifest file in the editor window:
![manifest file android](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yy8ck5k6y5qdstk2qptz.png)
The highlighted part focuses on `MainActivity`. For an activity to be visible to the Android system, it must be declared in the manifest file using the `<activity>` tag. And this piece of XML
 
```
<intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
```
makes it the activity that the will be launched from the launcher screen.

---

Back to this piece of code:
```
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            FirstComposeAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}
```
If you've worked with views, the code should be slightly familiar. In here, our first visible step into compose starts from `setContent` which has a `content` parameter that takes in a composable function that returns `Unit` as its argument. This content value becomes the root view of the given activity. 
Take a look at `setContent`'s definition:

```
public fun ComponentActivity.setContent(
    ...
    content: @Composable () -> Unit
) {
    ...
}
```

Before moving ahead, let's slide into what a composable function is.

---

A Jetpack Compose app will primarily be made up of composable functions which serve as the building blocks of your app’s UI. You’ll create your UI With composable functions or composables for short. A composable function looks like any other normal function you can find in your code, except now it's marked with an
annotation  @Composable. This annotation serves as a tag on your function that tells Compose that it is specially made for producing UI. Let's look at a very basic composable function:

```

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}
```

We can see the annotation @Composable, and as previously pointed out, this makes Greeting a composable function. Let's notice how we started our function name with a capital letter following a PascalCase format. [Anytime your composable function returns Unit, you are advised to use PascalCase in writing its name](https://github.com/androidx/androidx/blob/androidx-main/compose/docs/compose-api-guidelines.md), and also to use a noun as the name. Focusing on the function we are calling next, Text(...), is a composable function that comes by default with Jetpack Compose. It prints the String value that was passed as an argument to its parameter "text" on-screen.
We've passed in a string template that references the parameter _name_, thus, whatever value will be called with Greeting will be what gets shown on-screen. 
The Text function’s declaration looks like this:

```
@Composable
fun Text(
    text: String,
    ...
) {
    ...
}
```

`If you’ve ever used views to create apps, this is similar to TextView.`

---

Now that we know what composable functions are, let's waltz back into analyzing the piece of code in our `MainActivity.onCreate ` method.

---

From here, our next step comes with `FirstComposeAppTheme` which provides our app's theme. We can use a theme to style our app by providing a pool of colors, typography, and shapes that we can use to not only fuse our brand into the app but also grant it a uniform look and feel that looks aesthetically pleasing and is also coherent. Jetpack Compose provides `MaterialTheme` as the default theming system, but for more control over our app's look an feel, we can choose to build something of our own from scratch.
In our case `FirstComposeAppTheme`, automatically created upon the creation of own new project, sits atop `MaterialTheme`. 
See the definition of `FirstComposeAppTheme` :

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

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

Let's focus on the part about `MaterialTheme`, where clearly, our `FirstComposeAppTheme` just wraps around `MaterialTheme`.
Now back to our code in our activity's onCreate function, we can see that `setContent` is a [higher-order function](https://kotlinlang.org/docs/lambdas.html#lambda-expression-syntax), so is `FirstComposeAppTheme` and `Surface` since they take in functions as parameters. Notice the `FirstComposeAppTheme` was passed as an argument to the content parameter, using the trailing lambda syntax. Composable, `Greeting`, is called in the lambda passed into `Surface` with the parameter "Android". Since we have “Hello $name” already set, this should later show "Hello Android" on-screen once it is run.
The comment above the invocation of Surface, 

```
// A surface container using the 'background' color from the theme
                Surface(color = ...
```

tells us that we are creating a surface container and passing in the background color set in our theme. 
This surface container is a Material surface, meaning that it follows Material Design language where it serves as a depiction of physical surfaces having attributes like color, elevation, opacity and shape. See it’s definition:
@Composable
fun Surface(
    modifier: Modifier = Modifier,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(color),
    border: BorderStroke? = null,
    elevation: Dp = 0.dp,
    content: @Composable () -> Unit
) {
…
}

You might have noticed by now how a composable is passed into another composable as its `content`'s argument. 

Treading down our `MainActivity` file allows us to see the declaration of Greeting. Below it we can see another composable function `DefaultPreview` which takes no parameter but instead has an extra annotation `Preview`. The Android Studio you installed comes with a preview window that allows you to view the UI built by a composable. This `Preview` annotation marks a function that contains no parameter to allow its UI be shown in the Android Studio preview. 

```
@Preview(showBackground = true)
@Composable fun DefaultPreview() {
    FirstComposeAppTheme {
        Greeting("Android")
    }
}
```

![default preview android studio](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cbemwf17piadz4h2iax.png)
 
In the `DefaultPreview` function, `FirstComposeAppTheme` function is called and the same thing done in the `onCreate` function of the MainActivity is repeated. We can pass in several arguments to `Preview` that control how the UI created by the composable functions we call will look like in the preview window. For example, we can supply `showSystemUi = true`. 

```
@Preview(showBackground = true, showSystemUi = true )
```
At the moment, we are only tweaking the values of `showBackground` and `showSystemUi`, to see more info about the annotation, place you mouse icon over the annotation text and wait for a pop-up to appear showing the documentation details of `Preview`. If nothing appears, place your input cursor in the midst of its characters, go up to toolbar area, click **View** > **Quick Documentation**. You should probably take note of the shortcut for this action. 

---

The preview window should be open by default,
![android studio default preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bfntvtptrvnf2ruhb9ql.png)
but if it isn't, you can split the window. 

![android studio default preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qsecmybadl6q3qjjglh3.png) 

Using the preview window, you can always create composables and then see how they look before deploying to your device.

---

Now that we've taken our first steps with compose, let's actually start dancing in my next post.

`Main Sources:
Android source code`