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

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

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

Kirill Rozov

May 20, 2021
Tweet

More Decks by Kirill Rozov

Other Decks in Programming

Transcript

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

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

    такое Compose 👉 Каким образом Compose меняет разработку UI 👉 Будущее Compose 👉 Мультиплатформенный UI 4
  3. 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
  4. 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
  5. 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
  6. 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
  7. Типы собственных View 👉 Полностью свой View 👉 Расширение существующих

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

    бизнес логики (Kotlin/JAVA) 👉 View xранит состояние (set методы + атрибуты) 👉 Зависимость от платформы 👉 Высокая сложность создания собственных View 👉 Синхронное API с вызовами только с главного/UI потока 👉 Много кода в View. Очень много! 
 Класс View содержит 30000+ строк в Android 11.0 17
  9. 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
  10. 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
  11. 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
  12. Концепции Jetpack Compose 👉 Декларативный (описываете результат) 👉 Единый язык

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

    логики 👉 Хранит состояние 👉 Зависимость от платформы 👉 Высокая сложность создания собственных View 👉 Синхронное API с вызовами только с главного/UI потока 👉 Много кода в View. Очень много! 24
  14. @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
  15. Превью в 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
  16. Списки @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
  17. Списки @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
  18. Списки @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
  19. Списки @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
  20. Списки @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
  21. 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
  22. 40

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

    👉 Асинхронное и многопоточное построение UI 43
  24. Декомпозиция функционала 👉 Activity Result API 👉 OnBackPressedDispatcher 👉 SavedStateRegistry

    👉 ViewModel 👉 Lifecycle 👉 ViewTreeLifecycleOwner 👉 ViewTreeViewModelStoreOwner 👉 ViewTreeSavedStateRegistryOwner 47
  25. Недостатки Jetpack Compose ⛔ Поддерживает только Kotlin (а плохо ли?)

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

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