July 7, 2023

Jetpack Compose- chapter 1

In order to thoroughly confuse myself, I am working my way through this book in parallel with the "Building Android Apps" book.

Get the book resources from Github:

I clone the whole thing as follows:
cd /u1/Projects/Android
git clone https://github.com/PacktPublishing/Android-UI-Development-with-Jetpack-Compose.git
cd ..
ln -s Android/Android-UI-Development-with-Jetpack-Compose Compose
This will allow me to reference the book resources via /u1/Projects/Compose/chapter_01

Try just opening the first project in place

This would be: /u1/Projects/Compose/chapter_01/hello.
I just use File -- open to navigate to the above path.

It takes a while to open. The progress bar at the bottom of the android studio screen shows that it is busy doing a "Gradle sysnc". When it finishes I get the usual project navigation stuff on the left and an empty screen on the right. No warnings. I click the green triangle. After a short bit, it launches the "Hello" application in the Pixel 6 device manager window!

Under "app/java/..." I find MainActivity.kt and start looking at it.

String resources

One thing I notice right away as I study the code. Android studio is hiding the use of "string resources". Looking at the code in android studio I see:

Text(text = stringResource("Your name"))
The book shows the following (and that is really what is in the source file)
Text(text = stringResource(id = R.string.hint))
The strings themselves are actually in "strings.xml" (which is in res/values/strings/strings.xml). This naturally gets promoted as "best practices" -- but why? The only reason I have ever heard that really makes sense is if you want to change languages.

Android studio will help with this. I can type:

Text(text = "dog"))
Android studio places a "light bulb" on the line with various suggestions. It does happily accept this though, which I appreciate.

I can place the cursor on the "o" in "dog" and it suggests that I type ALT-Enter, and when I do, one of the options is "extract string resource". Let's try this. It brings up a dialog that lets me name the resource and give its value. I name the resource "doghint" and I end up with:

Text(text = stringResource(R.string.doghint))
An entry has magically been added for me in strings.xml If I want to change the value of the resource, I must edit strings.xml now.

Composable functions

Presumably more about this will be explained further along in the book, but for now just know that you must flag certain functions as "composable" in the following way:
@Composable
fun Greeting(name: String) {
}
This leaves a person wondering what other things can be introduced via lines that begin with an "@". We will soon meet @Preview. Also consider that this whole Jetpack Compose business is done via a compiler plugin. Yes, Kotlin offers the ability to extend the language itself via plugins. So, just bear in mind that we aren't just adding a library API, but actually modifying Kotlin itself.

remember and mutableStateOf?

This is interesting magic. It has to do with recomposition (when things are redrawn). Any composable function that depends on state is redrawn (recomposed) when that state changes. This leads to another topic called "state hoisting"

Compose preview

As near as I can tell, this doesn't work very well. I use an emulated Pixel 6 in the Device Manager, and it may be that this interferes with the preview business. Whatever the case, seeing the code run in the emulator gives me what I want. Perhaps the preview (if it worked) would be much faster and allow quick iteration, I don't know.

The idea is to be able to view a composable function without running the app. It would be nice if it worked, but it doesn't. Maybe in some future (or past) version of Android Studio. I am working with Flamingo.

MainActivity

For Compose, this inherits from ComponentActivity, which is different. A setContent {} block calls some composable function and away you go. A view based app would call setContentView(), probably with the argument R.layout.activity_main.

Notice also that composable functions are not part of a class, but are top-level functions. It is possible to mix traditional view based interfaces and composables.


Have any comments? Questions? Drop me a line!

Adventures in Computing / tom@mmto.org