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

Jetpack Compose - Hands-on February 2020

Jetpack Compose - Hands-on February 2020

Hands-On presentation on Jetpack Compose delivered at the Kotlin Meetup NYC as of version `dev-04`, February 2020.

Avatar for Pedro Veloso

Pedro Veloso

February 19, 2020
Tweet

Other Decks in Technology

Transcript

  1. Pedro Veloso Twitter && Instagram: @pedronveloso Hands-On Jetpack Compose K

    o t l i n M e e t u p 2 0 2 0 | N Y C 2 0 2 0 Pedro Veloso Twitter && Instagram: @pedronveloso Hands-On Jetpack Compose K o t l i n M e e t u p 2 0 2 0 | N Y C 2 0 2 0
  2. Jetpack Compose “Jetpack Compose simplifies and accelerates UI development on

    Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs.” Source: https://developer.android.com/jetpack/compose
  3. Why and How? • Android Developers Backstage Episode 131 :

    • https://androidbackstage.blogspot.com/2020/01/episode-131-jetpack-compose-and.html • Understanding Compose (Dev Summit): • https://www.youtube.com/watch?v=Q9MtlmmN4Q0 • Offitial Website • https://developer.android.com/jetpack/compose
  4. • Not Stable • Not in RC • Not in

    Beta • Not in Alpha • THIS IS A DEV PREVIEW! ¡ Don’t use in production !
  5. T h e H O W | Y e t

    A n o t h e r W e a t h e r A p p l i c a t i o n • Display Current temperature, max and min • 2nd Screen with the forecast • Style the App • Forecast list must be scrollable Compose Weather
  6. Layouts C o l u m n R o w

    A r r a n g e m e n t A x i s A r r a n g e m e n t A x i s
  7. Flex F l e x i n g A 0.3

    Flex A LayoutFlexible(0.3f)
  8. Flex F l e x i n g A 0.3

    Flex A C C LayoutFlexible(0.3f)
  9. Flex F l e x i n g A 0.3

    Flex A C C LayoutFlexible(0.3f) 0.2 Flex LayoutFlexible(0.2f)
  10. Basic Elements T e x t 3 7 4 L

    O C I m a g e 1 0 0 L O C S p a c e r L a y o u t W i d t h L a y o u t H e i g h t C a r d 5 5 L O C
  11. Text /** * Simplified version of [Text] component with minimal

    set of customizations. */ @Composable fun Text( text: String, modifier: Modifier = Modifier.None, style: TextStyle? = null, softWrap: Boolean = DefaultSoftWrap, overflow: TextOverflow = DefaultOverflow, maxLines: Int = DefaultMaxLines )
  12. @Composable private fun MainScreen(){ Column { DrawBackground() } } override

    fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MaterialTheme { MainScreen() } } } @Composable fun DrawBackground() { DrawImage(image = imageResource(R.drawable.nyc_night_1)) } B a c k g r o u n d
  13. B O N S A I | P R E

    S E N T A T I O N data class CurrentWeather( val locationName: String, val curTemperature: Temperature, val forecast: WeatherForecast ) class Temperature(val celcius: Double) data class WeatherForecast( val maxTemperature: Temperature, val minTemperature: Temperature, val state: WeatherState ) enum class WeatherState(@DrawableRes val iconResId: Int, @StringRes val descriptionResId: Int) { SUNNY(R.drawable.ic_sunny, R.string.state_sunny), RAINY(R.drawable.ic_rainy, R.string.state_rainy), PARTLY_CLOUDY(R.drawable.ic_p_cloudy, R.string.state_p_cloudy), SNOWY(R.drawable.ic_snowy, R.string.state_snowy) } <string name="state_sunny">Sunny</string> <string name="state_rainy">Rainy</string> … D a t a M o d e l s
  14. @Composable fun Title(currentWeather: CurrentWeather) { Text(text = currentWeather.locationName, style =

    MaterialTheme.typography().h2 .copy(color = Color.White, fontWeight = FontWeight.W200, fontFamily = FontFamily("sans- serif-thin"))) } } T i t l e
  15. Theming val weatherTypography = Typography( h1 = TextStyle( fontWeight =

    FontWeight.W200, fontSize = 54.sp, color = Color.White ), subtitle1 = … val weatherThemeColors = lightColorPalette( primary = Color(0xFF116a9c), primaryVariant = Color(0xFF1e5371), onPrimary = Color.White, … @Composable fun WeatherTheme(children: @Composable() () -> Unit) { MaterialTheme(colors = weatherThemeColors, typography = weatherTypography, children = children) }
  16. A p p l y T h e m e

    setContent { WeatherTheme { Column { DrawBackground() Title(currentWeather) } } } @Composable private fun Title(cur: CurrentWeather) { Text( text = cur.locationName, style = MaterialTheme.typography().h2 ) }
  17. @Composable fun Title(cur: CurrentWeather) { Row(modifier = LayoutWidth.Fill, arrangement =

    Arrangement.Center) { Spacer(LayoutHeight(16.dp)) Text(text = currentWeather.locationName, style = MaterialTheme.typography().h2) } } C e n t e r Column { DrawBackground() Title(currentWeather) }
  18. T o d a y ’ s S t a

    t e Row( modifier = LayoutWidth.Fill, arrangement = Arrangement.Center) { Container(width = 32.dp, height = 32.dp) { DrawImage(image = imageResource( currentWeather.forecast.state.iconResId)) } // Empty Space. Spacer(LayoutWidth(8.dp) Text( text = stringResource( currentWeather.forecast.state.descriptionResId), style = MaterialTheme.typography().body2) }
  19. T o d a y ’ s F o r

    e c a s t @Composable fun CurrentWeatherBlock( current: CurrentWeather) { Column(modifier = LayoutWidth.Fill , arrangement = Arrangement.Center) { } } WeatherState(current) CurrentTemperature(current) MinMaxTemperatures(current)
  20. L a y o u t A d j u

    s t Column { DrawBackground() Title(currentWeather = cur) Spacer(modifier = LayoutFlexible(0.7f)) CurrentWeatherBlock(currentWeather = cur) Spacer(modifier = LayoutFlexible(0.3f)) }
  21. L i s t E l e m e n

    t fun WeatherForecastRow Row { … } Card(color = cardBackgroundColor, elevation = 8.dp) { Padding(left = 8.dp, right = 8.dp, top = 16.dp, bottom = 16.dp) { WeatherForecastRow(forecast) } } for (forecast in forecasts) { }
  22. Compose Models sealed class Screen { object MainScreen : Screen()

    object WeatherForecastScreen : Screen() } @Model object GlobalState { var currentScreen : Screen = Screen.MainScreen var currentWeather : CurrentWeather? = null var predictions: List<DayForecast> = emptyList() } fun navigateTo(screen: Screen){ GlobalState.currentScreen = screen }
  23. Single Activity setContent { Crossfade(GlobalState.currentScreen) { screen -> Surface {

    when (screen) { is Screen.MainScreen -> MainScreen() is Screen.WeatherForecastScreen -> WeatherListScreen() } } } } override fun onBackPressed() { if (GlobalState.currentScreen == Screen.WeatherForecastScreen) { navigateTo(Screen.MainScreen) } else { super.onBackPressed() } }
  24. AppBar TopAppBar( title = { Text(text = stringResource(R.string.app_name)) } )

    TopAppBar( title = { Text(text = stringResource(R.string.app_name)) }, navigationIcon = { VectorImageButton(R.drawable.ic_back) { navigateTo(Screen.MainScreen) } } )
  25. Thank You Pedr o V elo s o @ p

    e d r o n v e l o s o Q& A? O r f i nd m e a f te rwa rd s :)