Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jetpack Compose - Programando la UI en forma declarativa en Android con Kotlin

Jetpack Compose - Programando la UI en forma declarativa en Android con Kotlin

Las interfaces gráficas declarativas son una tendencia que se viene viendo en otras tecnologías, como React/React Native, Vue.js, Flutter, Litho y otros. En el caso de Android, Jetbrains y Google se encuentran desarrollando conjuntamente Jetpack Compose, el cual fue mostrado en el Google I/O de este año. Si te interesa adelantarte a la próxima forma de crear los layouts de tus apps, entonces en esta charla veremos los conceptos básicos y varias demos para que puedas empezar cuanto antes.

Facundo Rodríguez Arceri

November 02, 2019
Tweet

More Decks by Facundo Rodríguez Arceri

Other Decks in Programming

Transcript

  1. ¿Por qué? • Librerías > clases del SDK. • Retrocompatibilidad.

    • Complejidad para reutilizar Views. • Single source of truth. • Necesidad de minimizar el código necesario.
  2. ¿Por qué ahora? • Diez años de Android • Tendencia

    • Compatibilidad con layouts existentes • Kotlin ❤
  3. Hasta ahora... • Una Activity en Android constaba de dos

    partes: ◦ Clase (Java/Kotlin) ◦ Layout (XML)
  4. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
  5. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) greeting.text = "Hello Facu!" } }
  6. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContent { MaterialTheme { Greeting("Android") } } } } @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }
  7. @Composable • Funciones Kotlin simples. • La anotación hace la

    magia ✨ • ¡No genera Views convencionales! • Son reinvocadas cada vez que cambian los parámetros de entrada.
  8. ¿Qué puedo hacer con ellas? • ¡Lo que quieras, es

    código Kotlin! • Composición por sobre herencia
  9. data class Player(val name: String, val number: Int) class MainActivity

    : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val players = arrayListOf( Player("Nicolas Tagliafico", 3), Player("Leandro Paredes", 5), Player("Sergio Agüero", 9), Player("Lionel Messi", 10) ) setContent { PlayersList(players) } } }
  10. @Composable fun PlayerRow(player: Player) { Padding(padding = EdgeInsets(left = 32.dp,

    right = 16.dp, top = 8.dp, bottom = 8.dp)) { Row { Text( text = "${player.number}", style = TextStyle(fontWeight = FontWeight.Bold) ) WidthSpacer(width = 24.dp) Text(text = player.name) } } }
  11. Flujo de datos • La idea es simplificar la arquitectura.

    • Las @Composable reciben los objetos que dibujan. • Los eventos que ocurren en una @Composable deben ser delegados a quien la invocó.
  12. @Composable fun PlayersList(players: List<Player>) { Column { players.forEach { PlayerRow(it,

    listener = { Toast.makeText(baseContext, "Clickeaste a ${it.name}", Toast.LENGTH_SHORT) .show() }) } } }
  13. @Composable fun PlayerRow(player: Player, listener: ((Player) -> Unit)) { Clickable(onClick

    = { listener(player) }) { Padding(padding = EdgeInsets(left = 32.dp, right = 16.dp, top = 8.dp, bottom = 8.dp)) { Row { Text( text = "${player.number}", style = TextStyle(fontWeight = FontWeight.bold) ) WidthSpacer(width = 24.dp) Text(text = player.name) } } } }
  14. Reaccionando a cambios en el estado • El estado de

    la pantalla debe ser almacenado en alguna @Composable. • Dicho estado debe ser observable. • Las @Composables correspondientes deben ser reinvocadas cuando algún atributo del estado cambia.
  15. @Model • Genera una nueva clase. • Atributos observables. •

    Thread-safe. • Cuando una @Composable acceda a un atributo, será reinvocada cada vez que dicho atributo cambie.
  16. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContent { MyApp() } } }
  17. @Composable fun MyApp(model: MainActivityModel = MainActivityModel()) { MaterialTheme { FlexColumn

    { inflexible { Button(text = "Agregar jugador", onClick = { model.players.add(Player("Nuevo jugador ${model.players.size}", model.players.size)) model.players = model.players }) } flexible(flex = 1f) { PlayersList(model.players) } } } }
  18. Links útiles • Documentación - https://d.android.com/jetpackcompose • Codelab - https://codelabs.developers.google.com/codelabs/jetpack-compose-basics

    • Android Dev Summit 2019 - https://www.youtube.com/user/androiddevelopers/playlist • Android Devs Bs As - https://www.twitter.com/AndroidDevsBsAs