Compose'da kullanıcı arayüzü sabittir. Çizildikten sonra bu arayüzün güncellenmesi mümkün değildir. Kullanıcı arayüzünüzün durumunu kontrol edebilirsiniz. Kullanıcı arayüzünün durumu her değiştiğinde, Compose kullanıcı arayüzü ağacının değişen bölümlerini yeniden oluşturur. Oluşturulabilir öğeler, durumu kabul edebilir ve etkinlikleri gösterebilir. Örneğin,
TextField bir değeri kabul eder ve geri çağırma işleyicinin değeri değiştirmesini isteyen bir geri çağırma
onValueChange gösterir.
var name by remember { mutableStateOf("") } OutlinedTextField( value = name, onValueChange = { name = it }, label = { Text("Name") } )
Oluşturulabilir öğeler durumu kabul ettiğinden ve etkinlikleri açığa çıkardığından tek yönlü veri akışı kalıbı Jetpack Compose'a uygundur. Bu kılavuz, Compose'da tek yönlü veri akışı kalıbının nasıl uygulanacağına, etkinliklerin ve durum sahiplerinin nasıl uygulanacağına ve Compose'da ViewModels ile nasıl çalışabileceğinize odaklanmaktadır.
Tek yönlü veri akışı
Tek yönlü veri akışı (UDF), durumun aşağı doğru indiği ve etkinliklerin yukarı çıktığı bir tasarım kalıbıdır. Tek yönlü veri akışını uygulayarak kullanıcı arayüzünde durumu görüntüleyen besteleri, uygulamanızın durumu depolayan ve değiştiren bölümlerinden ayırabilirsiniz.
Tek yönlü veri akışı kullanan bir uygulama için kullanıcı arayüzü güncelleme döngüsü şöyle görünür:
- Etkinlik: Kullanıcı arayüzünün bir bölümü, bir etkinlik oluşturur ve bunu, işlemesi için ViewModel'e iletilen bir düğme tıklaması gibi yukarı doğru iletir veya uygulamanızın diğer katmanlarından (örneğin, kullanıcı oturumunun sona erdiğini belirten) bir etkinlik aktarılır.
- Güncelleme durumu: Bir etkinlik işleyici durumu değiştirebilir.
- Görüntüleme durumu: Durum tutucu durumu iletir ve kullanıcı arayüzü bunu görüntüler.
Jetpack Compose'u kullanırken bu kalıbı izlemek çeşitli avantajlar sağlar:
- Test edilebilirlik: Durumun görüntülenen kullanıcı arayüzünden ayrıştırılması, her ikisinin de yalıtımda test edilmesini kolaylaştırır.
- Eyalet kapsülleme: Durum yalnızca tek bir yerde güncellenebileceği ve bir bestenin durumu için tek bir doğruluk kaynağı olduğu için tutarsız durumlar nedeniyle hata oluşturma olasılığınız daha düşüktür.
- Kullanıcı arayüzü tutarlılığı: Tüm durum güncellemeleri
StateFlowveya
LiveDatagibi gözlemlenebilir durum sahipleri kullanılarak kullanıcı arayüzüne anında yansıtılır.
Jetpack Compose'da tek yönlü veri akışı
Oluşturulabilir içerikler, duruma ve olaylara dayalı olarak çalışır. Örneğin, bir
TextField yalnızca
value parametresi güncellendiğinde güncellenir ve bir
onValueChange geri çağırması (değerin yeni değerle değiştirilmesini isteyen bir etkinlik) gösterir. Compose,
State nesnesini bir değer sahibi olarak tanımlar ve durum değerinde yapılan değişiklikler yeniden oluşturma işlemini tetikler. Değerini ne kadar süreyle hatırlamanız gerektiğine bağlı olarak durumu
remember { mutableStateOf(value) } veya
rememberSaveable { mutableStateOf(value) içinde tutabilirsiniz.
TextField composable öğesinin değerinin türü
String olduğundan bu değer, koda gömülmüş bir değerden, ViewModel'den veya üst composable öğeden iletilen herhangi bir yerden gelebilir. Bu değeri bir
State nesnesinde tutmanız gerekmez ancak
onValueChange çağrıldığında değeri güncellemeniz gerekir.
Oluşturulabilir parametreleri tanımlama
Oluşturulabilecek bir öğenin durum parametrelerini tanımlarken aşağıdaki soruları aklınızda bulundurmalısınız:
- Ne kadar yeniden kullanılabilir veya esnektir?
- Durum parametreleri bu beste öğesinin performansını nasıl etkiler?
Ayrıştırmayı ve yeniden kullanımı teşvik etmek için oluşturulan her dosyada mümkün olan en az miktarda bilgi bulunmalıdır. Örneğin, bir haber makalesinin başlığını tutacak bir kompozisyon oluştururken haber makalesinin tamamı yerine yalnızca görüntülenmesi gereken bilgileri aktarmayı tercih edin:
@Composable fun Header(title: String, subtitle: String) { // Recomposes when title or subtitle have changed. } @Composable fun Header(news: News) { // Recomposes when a new instance of News is passed in. }
Bazen bağımsız parametrelerin kullanılması performansı da artırır. Örneğin,
News,
title ve
subtitle dışında daha fazla bilgi içeriyorsa
title ve
subtitle değişmemiş olsa bile yeni
News örneği
Header(news) içine geçirildiğinde, oluşturulan rapor yeniden oluşturulur.
İlettiğiniz parametre sayısını dikkatlice düşünün. Çok fazla parametreye sahip bir işlevin olması, işlevin ergonomikliğini azaltır. Bu nedenle, bu durumda söz konusu işlevin bir sınıf halinde gruplandırılması tercih edilir.
Compose'daki etkinlikler
Uygulamanıza yapılan her giriş bir etkinlik olarak gösterilmelidir (dokunmalar, metin değişiklikleri,
hatta zamanlayıcılar ve diğer güncellemeler). Bu etkinlikler kullanıcı arayüzünüzün durumunu değiştirdiğinden, bunları işleyecek ve kullanıcı arayüzü durumunu güncelleyecek olan taraf
ViewModel olmalıdır.
Kullanıcı arayüzü katmanının durumu hiçbir zaman etkinlik işleyici dışında değişmemelidir. Aksi takdirde uygulamanızda tutarsızlıklar ve hatalar oluşabilir.
Durum ve etkinlik işleyici lambda'ları için sabit değerlerin iletilmesini tercih edin. Bu yaklaşım aşağıdaki avantajları sağlar:
- Yeniden kullanılabilirliği iyileştirmiş olursunuz.
- Kullanıcı arayüzünüzün durumun değerini doğrudan değiştirmediğinden emin olmanız gerekir.
- Durumun başka bir iş parçacığından dönüştürülmediğinden emin olduğunuz için eşzamanlılık sorunlarından kaçınırsınız.
- Genellikle kod karmaşıklığını azaltırsınız.
Örneğin, parametre olarak bir
String ve bir lambdayı kabul eden bir derleme, birçok bağlamdan çağrılabilir ve yüksek ölçüde yeniden kullanılabilir. Uygulamanızın üst tarafındaki uygulama çubuğunda her zaman metin gösterildiğini ve üzerinde geri düğmesi olduğunu varsayalım. Metni ve geri düğmesi tutma yerini parametre olarak alan daha genel bir
MyAppTopAppBar oluşturabilirsiniz:
@Composable fun MyAppTopAppBar(topAppBarText: String, onBackPressed: () -> Unit) { TopAppBar( title = { Text( text = topAppBarText, textAlign = TextAlign.Center, modifier = Modifier .fillMaxSize() .wrapContentSize(Alignment.Center) ) }, navigationIcon = { IconButton(onClick = onBackPressed) { Icon( Icons.Filled.ArrowBack, contentDescription = localizedString ) } }, // ... ) }
ViewModel'ler, durumlar ve etkinlikler: örnek
ViewModel ve
mutableStateOf kullanarak aşağıdaki durumlardan birinin geçerli olması halinde uygulamanıza tek yönlü veri akışı da sağlayabilirsiniz:
- Kullanıcı arayüzünüzün durumu,
StateFlowveya
LiveDatagibi gözlemlenebilir durum sahipleri aracılığıyla gösterilir.
ViewModel, kullanıcı arayüzünden veya uygulamanızın diğer katmanlarından gelen etkinlikleri işler ve etkinliklere göre durum sahibini günceller.
Örneğin, bir oturum açma ekranını uygularken Oturum aç düğmesine dokunmak, uygulamanızda ilerleme göstergesi ve ağ çağrısının gösterilmesine neden olmalıdır. Giriş başarılı olursa uygulamanız farklı bir ekrana gider. Hata durumunda uygulama bir Snackbar gösterir. Ekran durumunu ve etkinliği şu şekilde modelleyebilirsiniz:
Ekranda dört durum vardır:
- Oturum kapalıyken: Kullanıcı henüz oturum açmadığında.
- Devam ediyor: Uygulamanız şu anda bir ağ çağrısı gerçekleştirerek kullanıcının oturumunu açmaya çalışıyordur.
- Hata: Oturum açılırken bir hata oluştuğunda.
- Oturum açık: Kullanıcı oturum açtığında.
Bu durumları kapalı sınıf olarak modelleyebilirsiniz.
ViewModel, durumu
State olarak gösterir, başlangıç durumunu ayarlar ve gerekirse durumu günceller.
ViewModel, bir
onSignIn() yöntemini göstererek oturum açma etkinliğini de işler.
class MyViewModel : ViewModel() { private val _uiState = mutableStateOf<UiState>(UiState.SignedOut) val uiState: State<UiState> get() = _uiState // ... }
Compose,
mutableStateOf API'nin yanı sıra
LiveData,
Flow ve
Observable için işleyici olarak kaydolup değeri durum olarak temsil etmek üzere uzantılar sağlar.
class MyViewModel : ViewModel() { private val _uiState = MutableLiveData<UiState>(UiState.SignedOut) val uiState: LiveData<UiState> get() = _uiState // ... } @Composable fun MyComposable(viewModel: MyViewModel) { val uiState = viewModel.uiState.observeAsState() // ... }
Daha fazla bilgi
Jetpack Compose'daki mimari hakkında daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın: