Olá, Jetpack Compose
Tags: android, jetpackcompose, kotlin
Published: 2021-03-15 13:47:04

*Notas: Esse artigo está sendo escrito com base na versão 1.0.0-beta01 e tem como finalidade apresentar o novo sistema de UI para Android. No momento é necessário utilizar a versão canary do Android Studio para trabalhar com o Compose.*

O Jetpack Compose finalmente foi liberado como beta! E agora é a melhor hora para você começar a aprender sobre o novo sistema de UI do Android.

---

### O que é o Compose?

O Jetpack Compose é novo sistema de UI do Android, criado para substituir o atual (e já defasado) sistema de Views. Isso também faz com que o Android acompanhe as tendências de criação de UI declarativa, como ja existe com o SwiftUI, Flutter e React Native.

Algumas coisas muito legais sobre o Compose:

- 100% Kotlin: Isso permite tirar proveito total dessa poderosa linguagem.
- Desacoplado do sistema operacional: Isso permite que as atualizações e correções de bugs não dependam do sistema Android, e ainda possibilita usar o Compose em outras plataformas como desktop e web.

---

### Imperativo vs Declarativo

Antes de começar a trabalhar com o Compose, é bom saber as diferenças da criação de UI Imperativa (sistema atual) e UI declarativa (Compose).

Quando utilizamos o modelo imperativo, precisamos descrever como cada elemento da tela irá funcionar. Já no modelo declarativo, nós iremos dizer o que deverá acontecer em cada estado. Eu gosto de descrever esses dois paradigmas como: 

- Imperativo = "Faça isso!"
- Declarativo = "Seja isso."

Vamos ver um exemplo de como isso funciona.

Vamos supor que temos um `TextView` que mostra o saldo da conta e ele tem 2 estados. 

1. O texto deverá ser da cor verde caso o saldo seja maior ou igual a zero;
2. O texto deverá ser da cor vermelha caso o saldo seja menor que zero.

No modelo imperativo, isso ficaria mais ou menos assim:

```xml
<TextView
      android:id="@+id/tv_balance"
      android:layout_width="match_parent"
      android:layout_height="wrap_content" />
```

```kotlin
private fun updateBalance(balance: Double) {
	  val tvBalance = findViewById<TextView>(R.id.tv_balance)
	  if (balance >= 0) {
	    tvBalance.setTextColor(Color.GREEN)
	  } else {
	    tvBalance.setTextColor(Color.RED)
	  }
	  tvBalance.text = "$balance"
}
```

E no modelo declarativo:

```kotlin
@Composable
fun UserBalance(balance: Double) {
    Text(
        text = "$balance",
        color = if (balance >= 0) Color.Green else Color.Red,
    )
}
```

Olhando rapidamente a primeira coisa que é possível perceber nesse cenário, é que o código está mais simples na versão declarativa. Porém, esse não é o ponto mais importante. Perceba que no modelo declarativo o componente possui o seus estados internalizados, ou seja, ele *é isso*. No modelo imperativo é necessário mandar a view agir de tal forma, ou seja, estamos mandando que ele *faça isso*. 

---

### Como criar layouts com o Compose?

Os layouts no compose são criados através de uma árvore de elementos de UI, esses elementos são chamados de *composable functions*. 

Nós vimos um exemplo de como é uma *composable function* na explicação sobre o  paradigma de programação declarativa, a seguir veremos alguns outros exemplos para um melhor entendimento.

Primeiro vamos ver como criar uma função para apresentar um texto.

```kotlin
@Composable
fun Greeting(name: String = "Tiago") {
	Text("Olá, $name!")
}
```

Toda *composable function* deverá ser anotada com `@Composable`. Isso fará com que o compilador entenda que ele deverá transformar as informações de dentro da função em UI.

Nesse exemplo, foi criado uma *composable function* que recebe um parâmetro, esse parâmetro foi usado em outra *composable function* chamada `Text`. A função `Text` faz parte da biblioteca de UI do Compose e é responsável por renderizar um elemento de texto na tela.

O resultado é esse:

![Text simples sem nenhum modificador apresentando o texto "Olá, Tiago!"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rjuo4drm4yab4xlnmfs.png)

Os elementos respeitam a ordem que foram criados. Vamos ver um exemplo onde vários `Text` são apresentados na tela.

```kotlin
@Composable
fun Greeting(names: List<String> = listOf("Tiago", "Luiz", "Jefferson")) {
    for (name in names) {
        Text(text = "Olá, $name!")
    }
}
```

Esse é o resultado:

![Vários Text empilhados](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yjpd2lx43e7g5cwzmmi.png)

Perceba que todos os `Text` ficaram empilhados, e isso está correto! Isso aconteceu porque não foi especificado como eles deveriam ser apresentados. 

O Compose possui várias *composable functions* prontas, uma delas é a `Column`. Vamos ver um exemplo usando o `Column` para apresentar os `Text` um em baixo do outro.

```kotlin
@Composable
fun Greeting(names: List<String> = listOf("Tiago", "Luiz", "Jefferson")) {
    Column {
        for (name in names) {
            Text(text = "Olá, $name!")
        }
    }
}
```

Fazendo um comparativo com o sistema atual, o `Column` é similar ao `LinearLayout` na orientação vertical, para orientação horizontal, o Compose disponibiliza o componente `Row`.

Resultado:

![Column com 3 Texts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vy800x3uumdrc5g7croi.png)

Esses são alguns exemplos bem simples mostrando como apresentar elementos estáticos, mas e se for necessário fazer alguma atualização na tela? 

Toda vez que um componente tem seus dados alterados, ele passa por um processo chamado *recomposition*. Nesse processo o elemento é chamado novamente e o Compose é inteligente o suficiente para alterar apenas o necessário.

Vamos ver um exemplo de um `Button`:

```kotlin
@Composable
fun ClickCounterButton() {
    var numberOfClicks by remember { mutableStateOf(0) }
    Button(onClick = { numberOfClicks++ }) {
        Text(text = "Eu fui clickado $numberOfClicks vezes.")
    }
}
```

Nesse caso, toda vez que o `numberOfClicks` for alterado, o `Button` passará pelo recomposition.

Resultado: 

![Gif mostrando a funcionalidade de um counter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bt4blcmivthanovi5sa5.gif)

---

### Próximos passos

O propósito desse artigo foi apenas apresentar o novo sistema de UI do Android, ainda temos muitos conteúdos para ver, como: configuração de um projeto, states, modifiers, themes, layouts, etc. 

Esse artigo fará parte de uma série sobre Jetpack Compose, ainda teremos vários outros!

Espero que tenham gostado! Todos os feedbacks são bem-vindos.

Até a próxima!