Compose'da kullanıcı arayüzü sabittir. Çizildikten sonra güncellemenin bir yolu yoktur. Kullanıcı arayüzünüzün durumunu kontrol edebilirsiniz. Compose, kullanıcı arayüzünün durumu her değiştiğinde kullanıcı arayüzü ağacının değişen kısımlarını yeniden oluşturur. Composable, 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
sunar.
var name by remember { mutableStateOf("") } OutlinedTextField( value = name, onValueChange = { name = it }, label = { Text("Name") } )
composable'lar durumu kabul edip etkinlikleri ortaya çıkardığından tek yönlü veri akışı kalıbı Jetpack Compose'a uygundur. Bu kılavuzda, Compose'da tek yönlü veri akışı kalıbının nasıl uygulanacağı, etkinliklerin ve durum sahiplerinin nasıl uygulanacağı ve ViewModel'leriyle Compose'da nasıl çalışılacağı ele alınmaktadır.
Tek yönlü veri akışı
Tek yönlü veri akışı (UDF), durumun aşağı 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 durum görüntüleyen composable'ları, uygulamanızın durumunu 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 yukarı doğru aktarır (ör. işlemesi için ViewModel'e iletilen bir düğme tıklaması veya uygulamanızın diğer katmanlarından bir etkinlik (örneğin, kullanıcı oturumunun sona erdiğini belirten) iletilir).
- Güncelleme durumu: Bir olay 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 birçok avantaj sağlar:
- Test edilebilirlik: Durumun gösterildiği kullanıcı arayüzünden ayrılması, her iki durumun da yalıtımda test edilmesini kolaylaştırır.
- Durum kapsüllemesi: Durum yalnızca tek bir yerde güncellenebileceğinden ve bir composable'ın durumu için tek bir doğruluk kaynağı bulunduğundan 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
StateFlow
veyaLiveData
gibi gözlemlenebilir durum sahipleri kullanılarak kullanıcı arayüzüne hemen yansıtılır.
Jetpack Compose'da tek yönlü veri akışı
Composable'lar duruma ve etkinliklere göre ç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) sunar. Compose, State
nesnesini 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'ın değerinin türü String
olduğundan bu değer; sabit kodlu bir değerden, ViewModel'den veya üst composable'dan iletilen herhangi bir yerden gelebilir. Değeri bir State
nesnesinde tutmanız gerekmez, ancak onValueChange
çağrıldığında değeri güncellemeniz gerekir.
Oluşturulabilir parametreleri tanımlama
Bir composable'ın durum parametrelerini tanımlarken aşağıdaki soruları göz önünde bulundurmalısınız:
- Ne kadar yeniden kullanılabilir veya esnek bir composable?
- Durum parametreleri bu composable'ın performansını nasıl etkiler?
Ayrışmayı ve yeniden kullanmayı teşvik etmek için her composable mümkün olan en az miktarda bilgi içermelidir. Örneğin, bir haber makalesinin başlığını içerecek bir composable 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
yalnızca title
ve subtitle
dışında daha fazla bilgi içeriyorsa Header(news)
içine yeni bir News
örneği aktarıldığında title
ve subtitle
değişmemiş olsa bile composable yeniden oluşturulur.
İlettiğiniz parametre sayısını dikkatlice düşünün. Bir işlevin çok fazla parametreye sahip olması, işlevin ergonomisini azalttığından, bu durumda bunları bir sınıfta gruplandırmak tercih edilir.
Oluşturulan 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 kişi 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 lambdaları için sabit değerlerin geçirilmesini tercih edin. Bu yaklaşım aşağıdaki avantajları sağlar:
- Yeniden kullanılabilirliği iyileştirirsiniz.
- Kullanıcı arayüzünüzün, durumun değerini doğrudan değiştirmemesini sağlarsınız.
- 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.
- Çoğunlukla kod karmaşıklığını azaltırsınız.
Örneğin, parametre olarak String
ve lambda kabul eden bir composable, birçok bağlamdan çağrılabilir ve yüksek oranda yeniden kullanılabilir. Uygulamanızın üst tarafındaki uygulama çubuğunda her zaman metin görüntülendiğini ve geri düğmesi olduğunu varsayalım. Metni ve geri düğmesi tutma yerini parametre olarak alan daha genel bir MyAppTopAppBar
composable tanımlayabilirsiniz:
@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
kullandığınızda, aşağıdakilerden biri geçerliyse uygulamanızda tek yönlü veri akışı da sağlayabilirsiniz:
- Kullanıcı arayüzünüzün durumu,
StateFlow
veyaLiveData
gibi 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ı uygularken Oturum aç düğmesine dokunduğunuzda, uygulamanızda bir ilerleme durumu döner simgesi ve bir ağ çağrısı görüntülenir. Giriş başarılı olursa uygulamanız farklı bir ekrana gider. Hata durumunda uygulama bir Snackbar gösterir. Ekran durumu 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 o sırada bir ağ çağrısı gerçekleştirerek kullanıcının oturum açmasını sağlamaya çalışıyordur.
- Hata: Oturum açılırken bir hata oluştuğunda.
- Oturum açma: 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 durumu gerektiği gibi 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'ye ek olarak LiveData
, Flow
ve Observable
için işleyici olarak kaydolmak ve 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:
Numuneler
Sizin için önerilenler
- Not: Bağlantı metni JavaScript kapalıyken görüntülenir
- State ve Jetpack Compose
- Oluşturma penceresinde kullanıcı arayüzü durumunu kaydetme
- Kullanıcı girişini işleme