Suggestion: What if there is a preview button (nex...
# compose
p
Suggestion: What if there is a preview button (next to @Composable functions) in the gutter just like Run button in psvm?
Copy code
1 👁️ | @Composable
2    | fun Greeting(name: String = "Android") {
3    |    Text (text = "Hello $name!")
4    | }
g
That's really cute. File a feature request!
👍 8
l
Wouldn’t this be more a AS plugin?
f
This should definitely be part of the Android plugin.
👍🏼 4
r
Except composables might require more scaffolding to work
Like a theme for instance
This would work for simple cases
l
@romainguy how would this affect the plugin and not the annotation?
f
I think he means that this would do the same as annotating
@Preview
and going to the preview screen.
👍🏼 1
Really, that sounds a lot more convenient than having to write an annotation and delete it after
👌 2
r
My point is that it might not be possible to preview any composable as is.
f
Are you saying the
@Preview
annotation is pointless 🤔
r
Not at all. You can write a composable function with the data and scaffolding you need and annotate that with the preview annotation
But you might also be able to just annotate your compostable directly. It depends on what you need
And you can write several previews for a composable this way, to test different color schemes, data etc.
f
So you insert information about the compostable inside the params of the
@Preview
annotation. Haven't seen that yet.
r
No, you write a composable function that does that
For instance I have a
PhotoCard()
composable, but my preview will be:
Copy code
@Preview
fun PhotoCardPreviewDark() {
   val testData = ...
   MaterialTheme(darkTheme) {
      PhotoCard(testData)
   }
}
The preview annotation does have parameters like width/height but I don't know if they work yet
f
Oh, I see what you mean. Either way, a "Play" button on
PhotoCardPreviewDark
would be useful.
Would be interesting to have a way to avoid this ceremony for previewing components though.
r
What would the play button do? The interesting thing about @Preview is that it will show you all previews in the current file at the same time
👍 2
Which lets you display the same component with different configurations, test data, etc.
f
Maybe, just insert the text itself of the annotation? 😅
At this point it's not too important/useful though
r
Eh, yeah 🙂
Anyway we are definitely open to feedback, we want to make this as nice as possible
f
It can be a refactoring/quickfix/button that takes this
Copy code
@Composable fun MyButton(size : Int)  = /**/
And generates this
Copy code
@Preview 
fun MyButtonPreview(){  
    MaterialTheme( <--- cursor goes here first with a default value of lightTheme){
       MyButton( <--- cursor then goes here)
   }
}
You know, I think that's almost possible with IntelliJ live templates 🤔
c
I think I generally like
@Preview
more than a run button. Seeing all of the previews is nice. I think it’s a bit confusing with how it is presented though… I think my assumption was I’d just add
@Preview
to the component I’d use in production, that doesn’t seem to be the use-case though.
2
f
Considering you won't have the material theme, it's unlikely @Preview will be useful on a normal component
r
@Cody Engel You could, if your composable doens’t need any other setup
c
Are there many use cases for that? I started to extract the hello world sample and pretty quickly needed to pass parameters to the composables
r
Of standalone composables?
f
It's actually very similar to unit testing, some things don't depend on any data so you can just run them, and for some things you need mock data
c
So I wanted to add a Model to the sample which looks like this:
Copy code
@Model
class Name(var name: String)

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            HelloForm()
        }
    }

}

@Composable
fun HelloForm(name: Name = Name("Android")) = MaterialTheme {
    val name = Name("Android")
    Column {
        Greeting(name = name.name)
        Button(text = "New Name", onClick = { name.name = "Cody" } )
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}
And then I created a
ComposePreviews
Kotlin file with this:
Copy code
@Preview
@Composable
fun HelloFormNormal() {
    HelloForm(Name("Test"))
}
Which is probably fine, it’s a little weird that anyone could call
HelloFormNormal
though, it feels more like documentation to me than something I’d want others to actually call
r
You could put it in a separate file too
Does it work when making it private?
c
Making it private breaks it
r
Maybe that’s what we should do, make previews work when private
c
I will say though this tooling is still fantastic in the current state, I never thought I’d see Android get to this point and it’s really exciting 🙂
z
Late to this thread, but wouldn't you want to put preview functions in a different variant? I would think you'd want to avoid shipping the bytecode for them in your library/app.
☝️ 2
r
You can do that, or use R8 to strip out the code that doesn’t get used
👍 1
c
Putting the code in a separate build variant? I don’t think variants are really discussed much so making that a best practice seems weird... I think letting R8 do the heavy lifting would be more practical.