4 powody, dla których Jetpack Compose jest lepszy niż XML
Jetpack Compose to nowoczesne narzędzie UI od Google. Jego pierwsze stabilne wydanie ukazało się w lipcu 2021 roku i jak dotąd wielu programistów Kotlina uwielbia ten nowy sposób projektowania UI w Androidzie. Zobaczmy kilka świetnych przykładów zastosowania Jetpack Compose i tego, czym różni się od tradycyjnego XML.
Deklaratywny UI
Do tej pory w Androidzie używaliśmy UI imperatywnego. Pobieraliśmy element i jego zawartość, następnie modyfikowaliśmy i na koniec aktualizowaliśmy ten sam element. Połączenie między Androidem a XML nie jest wydajne przy użyciu funkcji findViewById()
czy nawet kotlinx.synthetics
. Chociaż wprowadzenie ViewBinding i DataBinding jest dobre, wymagana konfiguracja jest dość uciążliwa.
Deklaratywny UI to taki, w którym stan ekranu jest wstępnie zdefiniowany, a elementy interfejsu są przeładowywane po wykryciu zmian w tym stanie. Przyjrzyjmy się prostemu przykładowi licznika przycisków:
class MainActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Box (modifier = Modifier.fillMaxSize().background(Color.White)) {
MainScreen()
}
}
}
@Composable
fun MainScreen() {
var count by remember { mutableStateOf(0) }
Column(
horizontalAlignment = Alignment.Center,
verticalArrangment = Arrangement.Center
) {
Text(text = count.toString())
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { count++ }) {
Text(text = "Click me")
}
}
}
}
Za każdym razem, gdy klikniemy przycisk, zmienia się wartość licznika, co powoduje rekompozycje funkcji Composable dla zaktualizowanego UI. Musimy się upewnić, że stany znajdują się wewnątrz bloku remember, ponieważ po rekompozycji poprzedni stan zostanie utracony.
Powiedz NIE RecyclerView
Tworzenie instancji RecyclerView w XML zawierało spore ilości powtarzalnego kodu. Potrzebowaliśmy układu elementu, ViewHoldera i Adaptera oraz konfiguracji w Activity/Fragment. Dzięki Jetpack Compose nie ma już potrzeby stosowania powtarzalnego kodu.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val messages = listOf(
Message("Kevin", "I am on my way"),
Message("Natasha", "Don't leave the stove on"),
Message("Peter", "He did it again!")
)
LazyColumn(modifier = Modifier.fillMaxSize().background(Color.White)) {
items(messages) { message ->
MessageRow(message)
}
}
}
}
@Composable
fun MessageRow(message: Message) {
Column(modifier = Modifier
.fillMaxWidth()
.border(1.dp, Color.Black)
.padding(8.dp)
) {
Text(text = message.receiver, fontWeight = FontWeight.Bold)
Text(text = message.content)
}
}
}
LazyColumn jest zamiennikiem wertykalnego RecyclerView. Ekran będzie renderował funkcje composable tylko wtedy, gdy pojawią się one na ekranie — jest to dobre rozwiązanie dla długich list z API. I ponieważ Jetpack Compose jest deklaratywnym frameworkiem UI, funkcje composables będą odtwarzane na nowo przy zmianie stanu.
Nawigacja
Jeśli chodzi o nawigację w normalnym XML-u, to była niemałym utrapieniem. W przypadku fragmentów musieliśmy mieć instancję klasy, a w przypadku pakietów zastępowaliśmy fragment wewnątrz kontenera. Po wprowadzeniu komponentu nawigacyjnego Jetpack nie było lepiej. Konfiguracja nie była idealna, ale nie dało się jej uniknąć. Jetpack Compose przychodzi na ratunek!
Wprawdzie nawigacja w Jetpack Compose mogłaby przejść pewną reformę, jeśli chodzi o sposób, w jaki jest używana, ale jest to świetna alternatywa dla nawigacji, którą znaliśmy do tej pory w XML.
Animacje
Nie można poruszyć tematu dotyczącego Jetpack Compose i nie wspomnieć o animacjach. Animacje to najlepsza funkcja Jetpack Compose. XML nie został stworzony do tworzenia skomplikowanych animacji, ale Jetpack Compose umożliwia to dzięki świetnemu interfejsowi.
Istnieje mnóstwo różnych sposobów animacji właściwości i funkcji composable. Widoczność można wyzwalać różnymi efektami wejścia/wyjścia za pomocą AnimatedVisibility, tworząc przejścia między elementami, a przede wszystkim używając animate*AsState, gdzie * reprezentuje typ danych, taki jak Int lub Float.
Jetpack Compose dostarcza wiele różnych konfiguracji, które można wykorzystać do dostosowania animacji do tego co chcesz uzyskać na ekranie.
Wniosek
Nie, wprowadzenie Jetpack Compose nie oznacza, że XML jest przestarzały. Google potrzebowało trzech lat, aby oficjalnie ogłosić, że Kotlin to ich język i wprowadzić toolkit UI, który działa tylko w Kotlinie. Analogicznie, w ciągu kilku lat Compose będzie preferowanym sposobem radzenia sobie z UI, przy czym Google będzie tworzyć nowe komponenty, które będzie można renderować tylko wtedy, gdy użyjesz Jetpack Compose.
Oryginalna wersja artykułu dostępna jest na medium.com.