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

Jetpack Compose - серебряная пуля Android UI

Jetpack Compose - серебряная пуля Android UI

2aec47eb9a940c619f05972f0db5aa00?s=128

Kirill Rozov

May 20, 2021
Tweet

Transcript

  1. Jetpack Compose Кирилл Розов@Android Broadcast Серебряная пуля Android UI

  2. 👉 Блоггер 👉 Android GDE 👉 Автор Telegram канала “Android

    Broadcast” 👉 Автор YouTube канала “Android Broadcast” Кирилл Розов @kirill_rozov @krlrozov
  3. None
  4. План 👉 Что не так с Android View 👉 Что

    такое Compose 👉 Каким образом Compose меняет разработку UI 👉 Будущее Compose 👉 Мультиплатформенный UI 4
  5. layout/activity_hello_world.xml <TextView xmlns:android="http: // schemas.android.com/apk/res/android" android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5" />

    5
  6. HelloWorldActivity.kt class HelloWorldActivity : ComponentActivity(R.layout.activity_hello_world) { private lateinit var textView:

    TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) textView = findViewById(R.id.text) setGreeting("Android") } fun setGreeting(name: String) { textView.text = "Hello, $name" } } 6
  7. class HelloWorldActivity : ComponentActivity(R.layout.activity_hello_world) { private lateinit var textView: TextView

    override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) textView = findViewById(R.id.text) setGreeting("Android") } fun setGreeting(name: String) { textView.text = "Hello, $name" } } 7
  8. Альтернативы findViewById() 👉 AndroidAnnotations 👉 ButterKnife 👉 Kotlin Synthetic 👉

    Android DataBinding/ViewBinding 8
  9. class HelloWorldActivity : ComponentActivity(R.layout.activity_hello_world) { private lateinit var textView: TextView

    override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) textView = findViewById(R.id.text) setGreeting("Android") } fun setGreeting(name: String) { textView.text = "Hello, $name" } } 9
  10. class HelloWorldActivity : 
 ComponentActivity(R.layout.activity_hello_world) { private val viewBinding: ActivityHelloWorldBinding

    
 by viewBinding() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setGreeting("Android") } fun setGreeting(name: String) { viewBinding.text.text = "Hello, $name" } } 10
  11. Android View - всё объекты

  12. RelativeLayout FrameLayout LinearLayout ConstraintLayout Какой Layout самый оптимальный для экрана

    X?
  13. Списки в Android RecyclerView RecyclerView.Adapter ViewHolder DiffUtil ItemAnimator LayoutManager 13

  14. Как много Custom View вам приходилось создавать?

  15. None
  16. Типы собственных View 👉 Полностью свой View 👉 Расширение существующих

    
 Обычно “закостылить” 👉 Собственный ViewGroup 👉 Группировка View в виджет 
 Например, виджет контакта 
 16
  17. Особенности Android View 👉 Разные языки для вёрстки (XML) и

    бизнес логики (Kotlin/JAVA) 👉 View xранит состояние (set методы + атрибуты) 👉 Зависимость от платформы 👉 Высокая сложность создания собственных View 👉 Синхронное API с вызовами только с главного/UI потока 👉 Много кода в View. Очень много! 
 Класс View содержит 30000+ строк в Android 11.0 17
  18. Декларативный UI под Android и iOS UI XML

  19. Jetpack Compose

  20. class HelloComposeActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContent { Greeting("Android") } } } @Composable fun Greeting(name: String) { Text( text = "Hello $name!", style = MaterialTheme.typography.h5 ) } 20
  21. class HelloComposeActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContent { Greeting("Android") } } } @Composable fun Greeting(name: String) { Text( text = "Hello $name!", style = MaterialTheme.typography.h5 ) } 21
  22. class HelloComposeActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContent { Greeting("Android") } } } @Composable fun Greeting(name: String) { Text( text = "Hello $name!", style = MaterialTheme.typography.h5 ) } 22
  23. Концепции Jetpack Compose 👉 Декларативный (описываете результат) 👉 Единый язык

    для логики и UI (Kotlin) 👉 Можно использовать всё чему вы привыкли в Kotlin 👉 Не зависит от платформы 👉 Асинхронное параллельное построение UI 23
  24. Особенности Android View 👉 Разные языки для вёрстки и бизнес

    логики 👉 Хранит состояние 👉 Зависимость от платформы 👉 Высокая сложность создания собственных View 👉 Синхронное API с вызовами только с главного/UI потока 👉 Много кода в View. Очень много! 24
  25. Динамический контент

  26. @Composable fun MultiGreeting(name: String) { Column { repeat(10) { Greeting(name)

    } } } 26
  27. Интерактивный режим в IDE

  28. @Composable fun Counter() { var counter by rememberSaveable { mutableStateOf(0)

    } Surface(modifier = Modifier.fillMaxSize()) { Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = counter.toString(), style = MaterialTheme.typography.h4 ) Spacer(modifier = Modifier.height(8.dp)) Row { Button(onClick = { counter ++ }) { Text(text = "+") } Spacer(modifier = Modifier.width((8.dp))) Button( enabled = counter > 0, onClick = { counter -- } ) { Text(text = "-") } } } } } 28
  29. Превью в Android Studio @Composable fun Counter() { var counter

    by rememberSaveable { mutableStateOf(0) } Surface(modifier = Modifier.fillMaxSize()) { Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = counter.toString(), style = MaterialTheme.typography.h4 ) Spacer(modifier = Modifier.height(8.dp)) Row { Button(onClick = { counter + + }) { Text(text = "+") } Spacer(modifier = Modifier.width((8.dp))) Button( enabled = counter > 0, onClick = { counter -- } ) { Text(text = "-") } } } } } 29 Compose Preview Android Studio Artic Fox Canary 15
  30. Списки

  31. Списки @Composable fun SimpleList(items: List<Any>) { LazyColumn { items(items.size) {

    i - > SimpleTextItem(items[i].toString()) } } } @Composable fun SimpleTextItem(text: String) { Text( text = text, style = MaterialTheme.typography.h5, modifier = Modifier.padding(8.dp) ) } 31
  32. Списки @Composable fun SimpleList(items: List<Any>) { LazyColumn { items(items.size) {

    i - > SimpleTextItem(items[i].toString()) } } } @Composable fun SimpleTextItem(text: String) { Text( text = text, style = MaterialTheme.typography.h5, modifier = Modifier.padding(8.dp) ) } 32
  33. Списки @Composable fun SimpleList(items: List<Any>) { LazyColumn { items(items.size) {

    i - > SimpleTextItem(items[i].toString()) } } } @Composable fun SimpleTextItem(text: String) { Text( text = text, style = MaterialTheme.typography.h5, modifier = Modifier.padding(8.dp) ) } 33
  34. Списки @Composable fun SimpleList(items: List<Any>) { LazyColumn { items(items.size) {

    i - > SimpleTextItem(items[i].toString()) } } } @Composable fun SimpleTextItem(text: String) { Text( text = text, style = MaterialTheme.typography.h5, modifier = Modifier.padding(8.dp) ) } 34
  35. Списки @Composable fun SimpleList(items: List<Any>) { LazyColumn { items(items.size) {

    i - > SimpleTextItem(items[i].toString()) } } } @Composable fun SimpleTextItem(text: String) { Text( text = text, style = MaterialTheme.typography.h5, modifier = Modifier.padding(8.dp) ) } 35
  36. Будущее Jetpack Compose

  37. Compose Android, Desktop & Web

  38. Jetpack Compose @Composable fun Counter() { var counter by rememberSaveable

    { mutableStateOf(0) } Surface(modifier = Modifier.fillMaxSize()) { Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = counter.toString(), style = MaterialTheme.typography.h4 ) Spacer(modifier = Modifier.height(8.dp)) Row { Button(onClick = { counter + + }) { Text(text = "+") } Spacer(modifier = Modifier.width((8.dp))) Button( enabled = counter > 0, onClick = { counter -- } ) { Text(text = "-") } } } } } 38
  39. Compose for Desktop Window(title = "Compose Desktop") { MaterialTheme {

    Counter() } } 39
  40. 40

  41. Где поддержка iOS?

  42. Производительность

  43. Производительность 👉 Не нужно парсить XML 👉 Оптимизация кода R8/ProGuard

    👉 Асинхронное и многопоточное построение UI 43
  44. Как изменится Android разработка

  45. None
  46. Fragment больше не нужен

  47. Декомпозиция функционала 👉 Activity Result API 👉 OnBackPressedDispatcher 👉 SavedStateRegistry

    👉 ViewModel 👉 Lifecycle 👉 ViewTreeLifecycleOwner 👉 ViewTreeViewModelStoreOwner 👉 ViewTreeSavedStateRegistryOwner 47
  48. Библиотеки Jetpack с поддержкой Compose 👉 Navigation 👉 Activity 👉

    Paging 3 👉 ViewModel 👉 Hilt 👉 Material 48
  49. Недостатки Jetpack Compose ⛔ Поддерживает только Kotlin (а плохо ли?)

    ⛔ Нужно использовать Kotlin Compiler Backend IR (Kotlin 1.4.30 или новее) ⛔ Поддерживается только в Android Studio Canary ⛔ Не все виджеты есть в Compose (возможно уже неактуально) ⛔ Не является нативным UI, а лишь его имитация (аля Flutter) ⛔ Над производительностью еще работают ⛔ Над тулингом еще работают (но уже много достигнуто) ⛔ minSdk=21 (Android 5.0) 49
  50. Преимущества Jetpack Compose ✅ minSdk=21 (Android 5.0) ✅ Один язык

    для всего ✅ Используйте ко мне чему привыкли в Kotlin. Например, Coroutine ✅ Не стоит заботиться о вложенности ✅ Возможность оптимизировать UI код (R8/ProGuard) ✅ Независимость от Android фреймворка ✅ Мультиплатформенное решение 50
  51. Jetpack Compose 1.0 ИЮЛЬ 2021

  52. Спасибо за внимание