<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mitchell Giles</title>
    <description>The latest articles on DEV Community by Mitchell Giles (@mrgiles).</description>
    <link>https://dev.to/mrgiles</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1246899%2F0683e316-a90f-46be-aadf-987a5ffeeefc.jpg</url>
      <title>DEV Community: Mitchell Giles</title>
      <link>https://dev.to/mrgiles</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mrgiles"/>
    <language>en</language>
    <item>
      <title>Demystifying Jetpack Compose Modifier Order</title>
      <dc:creator>Mitchell Giles</dc:creator>
      <pubDate>Thu, 04 Jan 2024 19:33:47 +0000</pubDate>
      <link>https://dev.to/mrgiles/demystifying-jetpack-compose-modifier-order-4285</link>
      <guid>https://dev.to/mrgiles/demystifying-jetpack-compose-modifier-order-4285</guid>
      <description>&lt;p&gt;One of the most powerful pieces of Jetpack Compose is the concept of Modifiers. These little pieces of code are some of the basic building blocks of compose and you cannot go far without using them. They are how you apply padding, set backgrounds, set borders, make things clickable, and so much more. For being at the foundation of your composable functions and for being used as much as they are; there is still a lot of confusion that can come because of these little bits of code. &lt;/p&gt;

&lt;p&gt;That confusion stems from primarily one thing: order. In Compose, you can and should be chaining the modifiers for a function together. The order they get chained can greatly affect things. One such example is applying padding on something that is clickable, whether you apply the padding before or after the clickable can affect how far the ripple extends.&lt;/p&gt;

&lt;p&gt;So lets dive into demystifying the order of modifiers and play around with some examples to solidify what we learn. &lt;/p&gt;

&lt;p&gt;Our starting point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Box(
    modifier = Modifier
        .size(400.dp)
        .background(Color.White)
) {
    Box(modifier = Modifier
        .background(Color.Red)
        .size(64.dp)
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is what that looks like:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iIjE2zfP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1muk9nsa7wdvuibom54n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iIjE2zfP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1muk9nsa7wdvuibom54n.png" alt="A white 400 by 400 square with a 64 by 64 red square in the top left corner" width="411" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we wanted to add some padding to the red square we have a few options but the two that may come to mind the most are:&lt;br&gt;
a) at the beginning of the modifier chain&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modifier
   .padding(8.dp)
   .background(Color.Red)
   .size(64.dp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;b) at the end of the modifier chain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modifier
   .background(Color.Red)
   .size(64.dp)
   .padding(8.dp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here are the results:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OEoOTJL2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7ruvhrtwii9dudkao8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OEoOTJL2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7ruvhrtwii9dudkao8d.png" alt="Two white squares, the left one represents option a. And has the red square spaced away from the edge. The right square's red square is still flush against the edge. " width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the above we can see that option a) is most likely the option we are wanting in this scenario. The red square has been moved away from the edges like we would expect padding to do. Some of you may be wondering what happened to option b). Why didn't the padding work there and what exactly did applying the padding at the end do?  Well we can see what happened by adding some more color.&lt;/p&gt;

&lt;p&gt;Lets add another background to the red square to show whats going on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modifier
   .background(Color.Red)
   .size(64.dp)
   .padding(8.dp)
   .background(Color.Black)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which now makes our result look like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pVVxnR8O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/esijw4zeghgq7gmtv3xf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pVVxnR8O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/esijw4zeghgq7gmtv3xf.png" alt="A white square with a red square in the top left corner. And then there is a black square directly in the center of the red square." width="405" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can see that when we put padding at the end of the modifier chain it applied that padding "inside" the box rather than to the box as a whole. So when it comes to spacing and placing things we want to apply the padding first. &lt;/p&gt;

&lt;p&gt;This is actually a beneficial pattern though. As we build out screens and components as composables it is very common to pass in a modifier as a parameter. Since we want to apply padding first this makes it incredibly easy to let a component worry about itself, while the parent composable that calls the component can apply padding to place the component appropriately. This makes for very reusable components.&lt;/p&gt;

&lt;p&gt;There are times though that we may want to apply padding not at the start of the chain. Say we want to apply a border to the red square, but we want that border spaced slightly out from the square. To get such affect we can do something like this to the modifier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modifier
   .padding(8.dp)
   .border(1.dp, Color.Black)
   .padding(2.dp)
   .background(Color.Red)
   .size(64.dp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RZa_Uudp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4ecq5ug2cly42df3q9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RZa_Uudp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4ecq5ug2cly42df3q9p.png" alt="A white square with a red square in the top left corner slightly spaced away from the edges, and the red square has a black border slight spaced out from it." width="405" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hopefully this help demystify what order you should be calling your modifiers in. When in doubt, try it out. I encourage you to explore and try different modifier orders to help better understand what is going on. But also don't be hard on yourself if its not clicking or you still fail to put something in the right order. I've been working with Compose for years now and still get it wrong.&lt;/p&gt;

&lt;p&gt;PS. If you are still wondering if you should apply the padding before or after the clickable. It really just depends on where you want the ripple. You have a Box that should contain its ripple, then apply the padding before clickable. If you have a list item or text, you may want to apply some padding after clickable so the ripple goes past the text. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Power Up Your Jetpack Compose Previews</title>
      <dc:creator>Mitchell Giles</dc:creator>
      <pubDate>Tue, 02 Jan 2024 20:46:44 +0000</pubDate>
      <link>https://dev.to/mrgiles/power-up-your-jetpack-compose-previews-3db4</link>
      <guid>https://dev.to/mrgiles/power-up-your-jetpack-compose-previews-3db4</guid>
      <description>&lt;p&gt;Jetpack Compose is the go to UI framework for modern Android app development. One of Compose's most useful features is the ability to easily preview your UI without having to run the entire app. These previews are very flexible, dynamic, and easy to write. &lt;br&gt;
So lets explore some of the ways we can get more out of Compose Previews.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Preview Pane&lt;/strong&gt;&lt;br&gt;
Any Composable function that is annotated with &lt;code&gt;@Preview&lt;/code&gt; will generate a preview of your function. These previews will show up in the preview pane, and this pane has some fun functionality built in. Each one of these previews that show have some unique functionality available to them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;UI Check Mode. Starting in Android Studio Iguana you can use the UI Check Mode to easily find adaptive and accessibility issues with your UI. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Animation Preview. If you composable function has any animations inside of it, when you make a preview you can also view the Animation Preview. Inside this unique type of preview view you can play your animation, scrub through it,  and turn on and off pieces of the animation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interactive Mode. With Interactive Mode you can easily verify that your UI behaves correctly when it is being used. You can click on components works verifying that the interactions are correct (such as the ripple showing properly), scroll, and so much more. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run Preview. This makes it so the preview can be run on a connected device or emulator. Making it so you can easily see  how the UI looks on a real device without building your whole app. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Preview Annotation Class&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;@Preview&lt;/code&gt; that we add to make previews is actually a pretty powerful little piece of code. It is an Annotation Class that has a lot of optional parameters that we can use to change some how the preview is rendered and mimic some system level settings. This includes things like: locale, light or dark mode, font scales, and a lot more.&lt;/p&gt;

&lt;p&gt;As of Compose 1.5.4 the current parameters are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val name: String = "",
val group: String = "",
@IntRange(from = 1) val apiLevel: Int = -1,
val widthDp: Int = -1,
val heightDp: Int = -1,
val locale: String = "",
@FloatRange(from = 0.01) val fontScale: Float = 1f,
val showSystemUi: Boolean = false,
val showBackground: Boolean = false,
val backgroundColor: Long = 0,
@UiMode val uiMode: Int = 0,
@Device val device: String = Devices.DEFAULT,
@Wallpaper val wallpaper: Int = Wallpapers.NONE,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the following examples will be using this composable function and class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person(
    val firstName: String,
    val lastName: String,
    val phone: String,
    val email: String,
    val profilePictureUrl: String
) {
    val fullName = "$firstName $lastName"
}

@Composable
fun BasicCard(
    person: Person,
    modifier: Modifier = Modifier
) {
    Card(
        modifier = modifier.fillMaxWidth(),
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically
        ) {
            Icon(
                imageVector = ImageVector.vectorResource(id = R.drawable.ic_launcher_foreground),
                contentDescription = "Preview Profile Pic"
            )
            Column(
                modifier = Modifier.padding(end = 8.dp).padding(vertical = 8.dp)
            ) {
                Text(
                    text = person.fullName,
                    style = MaterialTheme.typography.headlineMedium,
                )
                Text(
                    text = person.phone,
                    style = MaterialTheme.typography.bodyMedium,
                )
                Text(
                    text = person.email,
                    style = MaterialTheme.typography.bodyMedium,
                )
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is the basic preview function for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Preview
@Composable
private fun BasicCardPreview() {
    MaterialTheme {
        BasicCard(
            modifier = Modifier.padding(8.dp),
            person = Person(
                firstName = "John",
                lastName = "Doe",
                phone = "(801) 123-4567",
                email = "john.doe@preview.com",
                profilePictureUrl = "https://www.google.com"
            )
        )
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is the preview that is generated:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pBQYQI33--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5puji67p5278opfslx8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pBQYQI33--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5puji67p5278opfslx8.png" alt="A screenshot of what the basic card looks like" width="362" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets start exploring some of the things we parameters we can use.&lt;/p&gt;

&lt;p&gt;If we replace the &lt;code&gt;@Preview&lt;/code&gt; with this &lt;code&gt;@Preview(showBackground = true, backgroundColor = 0xFFBA1B1B)&lt;/code&gt; our generated preview now looks like this: &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gTSBunzZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ox7m1qhfs4rqllz7553.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gTSBunzZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ox7m1qhfs4rqllz7553.png" alt="A screenshot showing a basic card with a red background behind the card" width="366" height="149"&gt;&lt;/a&gt;&lt;br&gt;
So now we can more easily see the curved corners and how it looks with spacing. &lt;/p&gt;

&lt;p&gt;While its nice to set a background when viewing individual components, the power of previews goes far beyond that. What makes compose previews really powerful is being able to adjust things like UI Mode (light vs dark mode) or Font Scales that are used with accessibility.&lt;br&gt;
To test out the font scale we can utilize another cool feature of compose functions. We can actually stack multiple preview annotations and Android Studio will generate a preview for each one. &lt;/p&gt;

&lt;p&gt;So lets replace that previous preview annotation with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Preview(
    name = "Large Font",
    fontScale = 2f
)
@Preview(
    name = "Normal Font",
    fontScale = 1f
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our preview pane has these two generated:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nWQBGZYf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o0uxkde0cxwtsrcu7hmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nWQBGZYf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o0uxkde0cxwtsrcu7hmg.png" alt="A screenshot showing two different basic cards with varying font sizes" width="366" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! Now we can easily see what our components are going to look like with a variety of different settings. But there is one small problem. It can be annoying to have to add all these additional preview annotations to every one of our composables that we are wanting to preview. Luckily there is an answer for that: Multipreview Annoations. &lt;/p&gt;

&lt;p&gt;With Multipreview Annoations we can create our own annotation classes that have these multiple different previews. Starting in Compose 1.6.0, compose will come with a few of these prebuilt (&lt;code&gt;@PreviewScreenSizes&lt;/code&gt;, &lt;code&gt;@PreviewFontScales&lt;/code&gt;, &lt;code&gt;@PreviewLightDark&lt;/code&gt;, and &lt;code&gt;@PreviewDynamicColors&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;To make our own multipreview annotation its as simple. As an example, say we are on Compose 1.5.4 so we don't have access to the prebuilt multipreview templates we can make our own by doing something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Preview(
    name = "small font",
    group = "font scales",
    fontScale = 0.5f
)
@Preview(
    name = "normal font",
    group = "font scales",
    fontScale = 1f
)
@Preview(
    name = "medium font",
    group = "font scales",
    fontScale = 1.5f
)
@Preview(
    name = "large font",
    group = "font scales",
    fontScale = 2f
)
annotation class FontScalePreviews
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we replace the &lt;code&gt;@Preview&lt;/code&gt; annotation with &lt;code&gt;@FontScalePreviews&lt;/code&gt; we will get these generated previews:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KG2UYGsy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/826txwp9hnba5l05779x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KG2UYGsy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/826txwp9hnba5l05779x.png" alt="A screenshot showing several basic cards with varying font sizes" width="371" height="788"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: We use the group parameter so inside the preview pane we can easily switch between showing the previews for "All", "font scales", or any other groups we define. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preview Parameter Provider&lt;/strong&gt;&lt;br&gt;
There is still one more trick we can use to make our previews do more for us. In the above BasicCard examples we were only showing the same info in every preview. But that might not be accurate of the actual functionality of the composable function. Composable functions often need to handle it being in different states. In this example, that could mean states where the user has really a really long name or maybe they have an empty phone number. We can easily just have multiple preview functions that have a different &lt;code&gt;Person&lt;/code&gt; passed into each one. But then we are maintaining a lot more functions and have duplicate code. The solution to this are: &lt;code&gt;Preview Parameter Providers&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;When we are working with a composable function that takes in a state object it can be beneficial to write a &lt;code&gt;Preview Parameter Provider&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;To make one we make a class that implements &lt;code&gt;PreviewParameterProvider&lt;/code&gt; and overrides the &lt;code&gt;values&lt;/code&gt; variable. For our &lt;code&gt;Person&lt;/code&gt; class it would end up looking something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private class PersonProvider: PreviewParameterProvider&amp;lt;Person&amp;gt; {
    override val values: Sequence&amp;lt;Person&amp;gt;
        get() = sequenceOf(
            Person(
                firstName = "John",
                lastName = "Doe",
                phone = "(801) 123-4567",
                email = "john.doe@preview.com",
                profilePictureUrl = "https://www.google.com"
            ),
            Person(
                firstName = "Jane",
                lastName = "Smith",
                phone = "",
                email = "jane.smith@preview.com",
                profilePictureUrl = "https://www.google.com"
            ),
        )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to use it we can rewrite our preview function to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Preview
@Composable
private fun BasicCardPreview(
    @PreviewParameter(PersonProvider::class) person: Person
) {
    MaterialTheme {
        BasicCard(
            modifier = Modifier.padding(8.dp),
            person = person
        )
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our generated previews look like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IGjff3cK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7pe4l0ibehacjzpuiwri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IGjff3cK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7pe4l0ibehacjzpuiwri.png" alt="A screenshot showing multiple Basic Cards with different information in each one" width="366" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would you look at that! We can easily see that there is an issue when the phone number is empty. So we could go in and fix that. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrap Up&lt;/strong&gt;&lt;br&gt;
If we utilize the available parameters inside the Preview Annotation Class we can easily make our previews reflect various system/device states and configurations. And if we use Preview Parameter Providers we can easily show our UI in various states of data. All without having to run our full app. &lt;br&gt;
That coupled with Live Edit and Live Literals we can easily iterate over our UI as we build it out and make changes. &lt;/p&gt;

</description>
      <category>androiddev</category>
      <category>compose</category>
      <category>mobile</category>
      <category>android</category>
    </item>
  </channel>
</rss>
