July 2, 2023
The import list up top shows an abbreviated ... but if I double click it expands to show me reality. They say that Jetpack Compose uses a Kotlin compiler plugin -- interesting that a compiler would have plugins and be extensible. I try just this code, building it and running it on a Pixel 6 API 33 virtual device.
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Text ( "Hello Tombstone") } } }This works just fine! It does take a while for the virtual device to boot up.
@Composable fun MessageCard(name: String) { Text(text = "Hello $name!") }This also works. Now they have me add this. They say @Preview functions may not have arguments.
@Preview @Composable fun PreviewMessageCard() { MessageCard("Android") }I am supposed to now get a preview window and a "split" view (design/code), but I don't get that at all. Maybe having a virtual device bypasses all of that.
I discover something interesting as I experiment around. I can click on a tiny "window" icon at the top right of the device manager and it becomes its own independent window I can move around. I can "redock" it by clicking on that same window icon that moves with the window.
I use View -- Tool Windows and look for Preview. It ain't there. So I'll just have to continue the tutorial and ignore all this stuff about Preview.
I discover later if I click the "_" (underscore) at the upper right of device manager, it goes away and reveals the Code/Split/Design trio. I find that with the size display I am using that Split just shoves "Design" (which apparently is the long lost preview window) right off on the right side. So clicking either Code or Design to show one or the other works well. If I ran Android Studio full screen, Split might work just fine.
I'll also note that whenever I rebuilt or restart my project, the Pixel 6 virtual device pops back into its original spot.
import androidx.compose.foundation.layout.Column data class Message ( val author: String, val body: String ) val n = Message ( "Levi", "Tombstone") MessageCard ( n ) @Composable fun MessageCard( msg: Message) { Column { Text(text = "Hello " + msg.author) Text(text = "Goodbye " + msg.body ) } }
import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Row import androidx.compose.ui.res.painterResource @Composable fun MessageCard(msg: Message) { Row { Image( painter = painterResource(R.drawable.profile_picture), contentDescription = "Contact profile picture", ) Column { Text(text = msg.author) Text(text = msg.body) } } }This leaves me wondering (and android studio also) as to where profile_picture is defined. At this point the tutorial has pretty much come unglued. Don't they all? Why don't the people writing them actually try them?
At some point I could research this "painter" business along with the R.drawable stuff and try to sort out how to make the connection. My bet is that the code above is just fine, but something else needs to be done to make profile_picture exist and point to girl.png
With some digging around I find girl.png in app/res/drawable. On disk, she is in app/build/intermediates/packaged_res/debug/drawable-tom and app/src/main/res/drawable-tom (all very mysterious).
More digging leads to a different method besides Resource manager. Go to app->res and right click. From the menu that appears select New, and from the next menu "Image Asset"
More digging leads to this enlightening statement:
When your Android application is compiled, a R class gets generated, which contains resource IDs for all the resources available in your res/ directory. You can use R class to access that resource using sub-directory and resource name or directly resource ID.Something for another day ...........
Adventures in Computing / tom@mmto.org