Kullanıcı arayüzü katmanı kılavuzunda, kullanıcı arayüzü katmanı için kullanıcı arayüzü durumunu oluşturma ve yönetme yöntemi olarak tek yönlü veri akışı (UDF) ele alınmaktadır.

Ayrıca, kullanıcı tanımlı işlev yönetimini durum tutucu adı verilen özel bir sınıfa devretmenin avantajlarını da vurgular. Durum tutucuyu ViewModel
veya düz bir sınıf aracılığıyla uygulayabilirsiniz. Bu belgede, durum tutucular ve kullanıcı arayüzü katmanındaki rolleri daha ayrıntılı bir şekilde ele alınmaktadır.
Bu belgenin sonunda, kullanıcı arayüzü katmanında uygulama durumunu (yani kullanıcı arayüzü durumu üretim ardışık düzenini) nasıl yöneteceğinizi anlamış olacaksınız. Aşağıdakileri anlamanız ve bilmeniz gerekir:
- Kullanıcı arayüzü katmanında bulunan kullanıcı arayüzü durumu türlerini anlama.
- Kullanıcı arayüzü katmanında bu kullanıcı arayüzü durumlarında çalışan mantık türlerini anlayın.
- Bir durum tutucunun (ör.
ViewModel
veya sınıf) uygun uygulamasını nasıl seçeceğinizi bilin.
Kullanıcı arayüzü durum üretimi ardışık düzeninin öğeleri
Kullanıcı arayüzü durumu ve bunu üreten mantık, kullanıcı arayüzü katmanını tanımlar.
Kullanıcı arayüzü durumu
Kullanıcı arayüzü durumu, kullanıcı arayüzünü tanımlayan özelliktir. İki tür kullanıcı arayüzü durumu vardır:
- Ekran kullanıcı arayüzü durumu, ekranda göstermeniz gereken şeydir. Örneğin, bir
NewsUiState
sınıfı, kullanıcı arayüzünü oluşturmak için gereken haber makalelerini ve diğer bilgileri içerebilir. Bu durum genellikle uygulama verilerini içerdiğinden hiyerarşinin diğer katmanlarıyla bağlantılıdır. - Kullanıcı arayüzü öğesi durumu, kullanıcı arayüzü öğelerinin oluşturulma şeklini etkileyen, öğelere özgü özellikleri ifade eder. Bir kullanıcı arayüzü öğesi gösterilebilir veya gizlenebilir ve belirli bir yazı tipi, yazı tipi boyutu ya da yazı tipi rengine sahip olabilir. Android Görünümleri'nde, Görünüm doğası gereği durumlu olduğundan bu durumu kendisi yönetir ve durumunu değiştirmek veya sorgulamak için yöntemler sunar. Buna örnek olarak, metin için
TextView
sınıfınınget
veset
yöntemleri verilebilir. Jetpack Compose'da durum, composable'ın dışındadır ve hatta composable'ın hemen yakınından composable işlevini çağıran veya bir durum tutucuya taşıyabilirsiniz. Buna örnek olarak,Scaffold
composable'ı içinScaffoldState
verilebilir.
Mantık
Uygulama verileri ve kullanıcı etkinlikleri, kullanıcı arayüzü durumunun zaman içinde değişmesine neden olduğundan kullanıcı arayüzü durumu statik bir özellik değildir. Mantık, değişikliğin ayrıntılarını (ör. kullanıcı arayüzü durumunun hangi bölümlerinin değiştiği, neden değiştiği ve ne zaman değişmesi gerektiği) belirler.

Bir uygulamadaki mantık, iş mantığı veya kullanıcı arayüzü mantığı olabilir:
- İş mantığı, uygulama verileriyle ilgili ürün şartlarının uygulanmasıdır. Örneğin, kullanıcı düğmeye dokunduğunda bir haber okuyucu uygulamasında makaleye yer işareti ekleme. Bir yer işaretini dosyaya veya veritabanına kaydetme mantığı genellikle alan veya veri katmanlarına yerleştirilir. Durum sahibi genellikle bu mantığı, sundukları yöntemleri çağırarak bu katmanlara devreder.
- Kullanıcı arayüzü mantığı, kullanıcı arayüzü durumunun ekranda nasıl görüntüleneceğiyle ilgilidir. Örneğin, kullanıcı bir kategori seçtiğinde doğru arama çubuğu ipucunu alma, listede belirli bir öğeye kaydırma veya kullanıcı bir düğmeyi tıkladığında belirli bir ekrana gitme mantığı.
Android yaşam döngüsü ve kullanıcı arayüzü durumu ile mantık türleri
Kullanıcı arayüzü katmanı iki bölümden oluşur: biri kullanıcı arayüzü yaşam döngüsüne bağlıdır, diğeri ise bağımsızdır. Bu ayrım, her bölümün kullanabileceği veri kaynaklarını belirler ve bu nedenle farklı türlerde kullanıcı arayüzü durumu ve mantığı gerektirir.
- Kullanıcı arayüzü yaşam döngüsünden bağımsız: Kullanıcı arayüzü katmanının bu kısmı, uygulamanın veri üreten katmanlarıyla (veri veya alan katmanları) ilgilenir ve iş mantığı tarafından tanımlanır. Yaşam döngüsü, yapılandırma değişiklikleri ve kullanıcı arayüzünde
Activity
yeniden oluşturma, kullanıcı arayüzü durumu üretim hattının etkin olup olmadığını etkileyebilir ancak üretilen verilerin geçerliliğini etkilemez. - Kullanıcı arayüzü yaşam döngüsüne bağlı: Kullanıcı arayüzü katmanının bu bölümü, kullanıcı arayüzü mantığıyla ilgilenir ve yaşam döngüsü ya da yapılandırma değişikliklerinden doğrudan etkilenir. Bu değişiklikler, içinde okunan veri kaynaklarının geçerliliğini doğrudan etkiler ve bu nedenle durumu yalnızca yaşam döngüsü etkin olduğunda değişebilir. Çalışma zamanı izinleri ve yerelleştirilmiş dizeler gibi yapılandırmaya bağlı kaynakları almak buna örnek verilebilir.
Yukarıdaki bilgiler aşağıdaki tabloda özetlenmiştir:
Kullanıcı arayüzü yaşam döngüsünden bağımsız | Kullanıcı arayüzü yaşam döngüsüne bağlı |
---|---|
İş mantığı | Kullanıcı Arayüzü Mantığı |
Ekran kullanıcı arayüzü durumu |
Kullanıcı arayüzü durumu üretim ardışık düzeni
Kullanıcı arayüzü durumu üretim hattı, kullanıcı arayüzü durumu üretmek için uygulanan adımları ifade eder. Bu adımlar, daha önce tanımlanan mantık türlerinin uygulanmasından oluşur ve tamamen kullanıcı arayüzünüzün ihtiyaçlarına bağlıdır. Bazı kullanıcı arayüzleri, işlem hattının kullanıcı arayüzü yaşam döngüsünden bağımsız ve kullanıcı arayüzü yaşam döngüsüne bağlı bölümlerinden birinden, her ikisinden veya hiçbirinden yararlanabilir.
Yani, kullanıcı arayüzü katmanı işlem hattının aşağıdaki permütasyonları geçerlidir:
Kullanıcı arayüzü durumu, kullanıcı arayüzü tarafından üretilir ve yönetilir. Örneğin, basit ve yeniden kullanılabilir bir temel sayaç:
@Composable fun Counter() { // The UI state is managed by the UI itself var count by remember { mutableStateOf(0) } Row { Button(onClick = { ++count }) { Text(text = "Increment") } Button(onClick = { --count }) { Text(text = "Decrement") } } }
Kullanıcı arayüzü mantığı → Kullanıcı arayüzü. Örneğin, kullanıcının listenin en üstüne gitmesine olanak tanıyan bir düğmeyi gösterme veya gizleme.
@Composable fun ContactsList(contacts: List<Contact>) { val listState = rememberLazyListState() val isAtTopOfList by remember { derivedStateOf { listState.firstVisibleItemIndex < 3 } } // Create the LazyColumn with the lazyListState ... // Show or hide the button (UI logic) based on the list scroll position AnimatedVisibility(visible = !isAtTopOfList) { ScrollToTopButton() } }
İş mantığı → kullanıcı arayüzü. Ekrandaki mevcut kullanıcının fotoğrafını gösteren bir kullanıcı arayüzü öğesi.
@Composable fun UserProfileScreen(viewModel: UserProfileViewModel = hiltViewModel()) { // Read screen UI state from the business logic state holder val uiState by viewModel.uiState.collectAsStateWithLifecycle() // Call on the UserAvatar Composable to display the photo UserAvatar(picture = uiState.profilePicture) }
İş mantığı → kullanıcı arayüzü mantığı → kullanıcı arayüzü. Belirli bir kullanıcı arayüzü durumu için ekranda doğru bilgileri göstermek üzere kaydırılan kullanıcı arayüzü öğesi.
@Composable fun ContactsList(viewModel: ContactsViewModel = hiltViewModel()) { // Read screen UI state from the business logic state holder val uiState by viewModel.uiState.collectAsStateWithLifecycle() val contacts = uiState.contacts val deepLinkedContact = uiState.deepLinkedContact val listState = rememberLazyListState() // Create the LazyColumn with the lazyListState ... // Perform UI logic that depends on information from business logic if (deepLinkedContact != null && contacts.isNotEmpty()) { LaunchedEffect(listState, deepLinkedContact, contacts) { val deepLinkedContactIndex = contacts.indexOf(deepLinkedContact) if (deepLinkedContactIndex >= 0) { // Scroll to deep linked item listState.animateScrollToItem(deepLinkedContactIndex) } } } }
Kullanıcı arayüzü durumu oluşturma işlem hattına her iki mantık türünün de uygulandığı durumlarda iş mantığı her zaman kullanıcı arayüzü mantığından önce uygulanmalıdır. Kullanıcı arayüzü mantığından sonra iş mantığını uygulamaya çalışmak, iş mantığının kullanıcı arayüzü mantığına bağlı olduğu anlamına gelir. Aşağıdaki bölümlerde, farklı mantık türleri ve durum tutucuları ayrıntılı bir şekilde incelenerek bunun neden bir sorun olduğu açıklanmaktadır.

Durum bilgisi depolayıcılar ve sorumlulukları
Durum tutucunun sorumluluğu, durumu depolayarak uygulamanın okumasını sağlamaktır. Mantığın gerekli olduğu durumlarda aracı görevi görür ve gerekli mantığı barındıran veri kaynaklarına erişim sağlar. Bu şekilde, durum sahibi mantığı uygun veri kaynağına devreder.
Bu durum aşağıdaki avantajları sağlar:
- Basit kullanıcı arayüzleri: Kullanıcı arayüzü yalnızca durumunu bağlar.
- Sürdürülebilirlik: Durum tutucuda tanımlanan mantık, kullanıcı arayüzü değiştirilmeden yinelenebilir.
- Test edilebilirlik: Kullanıcı arayüzü ve durum üretim mantığı bağımsız olarak test edilebilir.
- Okunabilirlik: Kodu okuyanlar, kullanıcı arayüzü sunum kodu ile kullanıcı arayüzü durumu üretim kodu arasındaki farkları net bir şekilde görebilir.
Boyutu veya kapsamı ne olursa olsun her kullanıcı arayüzü öğesi, karşılık gelen durum tutucusuyla 1:1 ilişkiye sahiptir. Ayrıca, durum tutucu, kullanıcı arayüzü durum değişikliğine neden olabilecek tüm kullanıcı işlemlerini kabul edip işleyebilmeli ve sonuçtaki durum değişikliğini oluşturmalıdır.
Durum sahibi türleri
Kullanıcı arayüzü durumu ve mantığına benzer şekilde, kullanıcı arayüzü katmanında kullanıcı arayüzü yaşam döngüsüyle ilişkilerine göre tanımlanan iki tür durum tutucu vardır:
- İş mantığı durum tutucusu.
- Kullanıcı arayüzü mantığı durum koruyucusu.
Aşağıdaki bölümlerde, işletme mantığı durum tutucudan başlayarak durum tutucu türleri daha ayrıntılı bir şekilde incelenmektedir.
İş mantığı ve durum tutucusu
İş mantığı durum tutucuları, kullanıcı etkinliklerini işler ve veri katmanlarındaki ya da alan katmanlarındaki verileri ekran kullanıcı arayüzü durumuna dönüştürür. Android yaşam döngüsü ve uygulama yapılandırma değişiklikleri göz önünde bulundurulduğunda en iyi kullanıcı deneyimini sağlamak için iş mantığını kullanan durum tutucular aşağıdaki özelliklere sahip olmalıdır:
Özellik | Ayrıntı |
---|---|
Kullanıcı arayüzü durumu üretir | İş mantığı durumu sahipleri, kullanıcı arayüzleri için kullanıcı arayüzü durumu oluşturmaktan sorumludur. Bu kullanıcı arayüzü durumu genellikle kullanıcı etkinliklerinin işlenmesi ve alan ile veri katmanlarından veri okunması sonucunda ortaya çıkar. |
Etkinlik yeniden oluşturularak korunur. | İş mantığı durumu sahipleri, Activity yeniden oluşturma sırasında durumlarını ve durum işleme işlem hatlarını koruyarak sorunsuz bir kullanıcı deneyimi sunmaya yardımcı olur. Durum tutucunun korunamadığı ve yeniden oluşturulduğu durumlarda (genellikle işlem sonlandırmadan sonra) tutarlı bir kullanıcı deneyimi sağlamak için durum tutucunun son durumunu kolayca yeniden oluşturabilmesi gerekir. |
Uzun süreli duruma sahip olma | İş mantığı durum tutucuları, gezinme hedeflerinin durumunu yönetmek için sıklıkla kullanılır. Bu nedenle, gezinme grafiğinden kaldırılana kadar gezinme değişikliklerinde durumlarını korurlar. |
Kullanıcı arayüzüne özeldir ve yeniden kullanılamaz. | İş mantığı durum tutucuları genellikle belirli bir uygulama işlevi için durum oluşturur (ör. TaskEditViewModel veya TaskListViewModel ) ve bu nedenle yalnızca söz konusu uygulama işlevi için geçerlidir. Aynı durum tutucu, farklı form faktörlerinde bu uygulama işlevlerini destekleyebilir. Örneğin, uygulamanın mobil, TV ve tablet sürümleri aynı iş mantığı durum tutucusunu yeniden kullanabilir. |
Örneğin, "Now in Android" uygulamasındaki yazar gezinme hedefini ele alalım:

İş mantığı durumunu tutan öğe olarak hareket eden AuthorViewModel
, bu durumda kullanıcı arayüzü durumunu oluşturur:
@HiltViewModel
class AuthorViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
private val authorsRepository: AuthorsRepository,
newsRepository: NewsRepository
) : ViewModel() {
val uiState: StateFlow<AuthorScreenUiState> = …
// Business logic
fun followAuthor(followed: Boolean) {
…
}
}
AuthorViewModel
öğesinin, daha önce belirtilen özelliklere sahip olduğunu unutmayın:
Özellik | Ayrıntı |
---|---|
Üretim: AuthorScreenUiState |
AuthorViewModel , AuthorsRepository ve NewsRepository kaynaklarından verileri okur ve bu verileri kullanarak AuthorScreenUiState oluşturur. Ayrıca, kullanıcı bir Author hesabını takip etmek veya takibi bırakmak istediğinde AuthorsRepository hesabına yetki vererek iş mantığını uygular. |
Veri katmanına erişimi olmalıdır. | Oluşturucusunda AuthorsRepository ve NewsRepository örnekleri geçirilir. Bu sayede, Author takip etme iş mantığını uygulayabilir. |
Activity yeniden oluşturulduğunda bozulmaz |
ViewModel ile uygulandığı için hızlı Activity yeniden oluşturma işleminde korunur. İşlem sonlandığında, kullanıcı arayüzü durumunu veri katmanından geri yüklemek için gereken minimum bilgi miktarını sağlamak üzere SavedStateHandle nesnesi okunabilir. |
Uzun süreli duruma sahip | ViewModel , gezinme grafiğiyle sınırlıdır. Bu nedenle, yazar hedefi gezinme grafiğinden kaldırılmadığı sürece uiState StateFlow içindeki kullanıcı arayüzü durumu bellekte kalır. StateFlow kullanımı, durum yalnızca kullanıcı arayüzü durumunun toplayıcısı varsa üretildiğinden, durumu üreten iş mantığının uygulamasını tembel hale getirme avantajını da sağlar. |
Kullanıcı arayüzüne özgü olmalıdır. | AuthorViewModel yalnızca yazarın gezinme hedefi için geçerlidir ve başka hiçbir yerde yeniden kullanılamaz. Gezinme hedefleri arasında yeniden kullanılan herhangi bir iş mantığı varsa bu iş mantığı, veri veya alan katmanı kapsamlı bir bileşende kapsüllenmelidir. |
ViewModel, iş mantığı durum tutucusu olarak
Android geliştirmede ViewModel'lerin avantajları, bu bileşenleri iş mantığına erişim sağlamak ve uygulama verilerini ekranda sunulmaya hazırlamak için uygun hale getirir. Bu avantajlar arasında şunlar yer alır:
- ViewModel'ler tarafından tetiklenen işlemler, yapılandırma değişikliklerinden etkilenmez.
- Navigasyon ile entegrasyon:
- Gezinme, ekran arka planda olduğunda ViewModel'leri önbelleğe alır. Bu, hedefinize döndüğünüzde daha önce yüklediğiniz verilerin anında kullanılabilmesi için önemlidir. Bu, composable ekranın yaşam döngüsünü takip eden bir durum tutucuyla yapılması daha zor bir işlemdir.
- ViewModel, hedef arka yığından çıkarıldığında da temizlenir. Böylece durumunuzun otomatik olarak temizlenmesi sağlanır. Bu, yeni bir ekrana gitme, yapılandırma değişikliği gibi çeşitli nedenlerle gerçekleşebilen birleştirilebilir öğelerin kaldırılmasını dinlemekten farklıdır.
- Hilt gibi diğer Jetpack kitaplıklarıyla entegrasyon.
Kullanıcı arayüzü mantığı ve durum bilgisi depolayıcısı
Kullanıcı arayüzü mantığı, kullanıcı arayüzünün kendisinin sağladığı veriler üzerinde çalışan mantıktır. Bu, kullanıcı arayüzü öğelerinin durumuna veya izin API'si ya da Resources
gibi kullanıcı arayüzü veri kaynaklarına bağlı olabilir. Kullanıcı arayüzü mantığını kullanan durum koruyucular genellikle şu özelliklere sahiptir:
- Kullanıcı arayüzü durumu üretir ve kullanıcı arayüzü öğelerinin durumunu yönetir.
- Yeniden oluşturma işleminden sonra
Activity
korunmaz: Kullanıcı arayüzü mantığında barındırılan durum tutucular genellikle kullanıcı arayüzünün kendisindeki veri kaynaklarına bağlıdır ve bu bilgileri yapılandırma değişiklikleri arasında korumaya çalışmak çoğu zaman bellek sızıntısına neden olur. Durum sahiplerinin yapılandırma değişikliklerinde verilerin kalıcı olması için başka bir bileşene yetki vermesi gerekir. Bu bileşen,Activity
yeniden oluşturma işlemine daha uygundur. Örneğin, Jetpack Compose'daremembered
işlevleriyle oluşturulan Composable kullanıcı arayüzü öğesi durumları,Activity
yeniden oluşturma işlemleri sırasında durumu korumak için genelliklerememberSaveable
'ye temsilci olarak atanır. Bu tür işlevlere örnek olarakrememberScaffoldState()
verememberLazyListState()
verilebilir. - Kullanıcı arayüzü kapsamlı veri kaynaklarına referanslar içerir: Yaşam döngüsü API'leri ve Kaynaklar gibi veri kaynaklarına güvenli bir şekilde referans verilebilir ve bu kaynaklar okunabilir. Bunun nedeni, kullanıcı arayüzü mantık durumu tutucusunun kullanıcı arayüzüyle aynı yaşam döngüsüne sahip olmasıdır.
- Birden fazla kullanıcı arayüzünde yeniden kullanılabilir: Aynı kullanıcı arayüzü mantığı durum tutucusunun farklı örnekleri, uygulamanın farklı bölümlerinde yeniden kullanılabilir. Örneğin, bir çip grubu için kullanıcı girişi etkinliklerini yöneten bir durum tutucu, filtre çipleri için bir arama sayfasında ve e-posta alıcılarının "alıcı" alanında kullanılabilir.
Kullanıcı arayüzü mantığı durum tutucusu genellikle düz bir sınıfla uygulanır. Bunun nedeni, kullanıcı arayüzü mantığı durum koruyucusunun oluşturulmasından kullanıcı arayüzünün kendisinin sorumlu olması ve kullanıcı arayüzü mantığı durum koruyucusunun, kullanıcı arayüzüyle aynı yaşam döngüsüne sahip olmasıdır. Örneğin, Jetpack Compose'da durum tutucu, Composition'ın bir parçasıdır ve Composition'ın yaşam döngüsünü takip eder.
Yukarıdaki durum, Now in Android örneğindeki aşağıdaki örnekle gösterilebilir:

Now in Android örneği, gezinme için cihazın ekran boyutuna bağlı olarak alt uygulama çubuğu veya gezinme sütunu gösterir. Daha küçük ekranlarda alt uygulama çubuğu, daha büyük ekranlarda ise gezinme rayı kullanılır.
NiaApp
composable işlevinde kullanılan uygun gezinme kullanıcı arayüzü öğesine karar verme mantığı, iş mantığına bağlı olmadığından NiaAppState
adlı düz sınıf durumu tutucusu tarafından yönetilebilir:
@Stable
class NiaAppState(
val navController: NavHostController,
val windowSizeClass: WindowSizeClass
) {
// UI logic
val shouldShowBottomBar: Boolean
get() = windowSizeClass.widthSizeClass == WindowWidthSizeClass.Compact ||
windowSizeClass.heightSizeClass == WindowHeightSizeClass.Compact
// UI logic
val shouldShowNavRail: Boolean
get() = !shouldShowBottomBar
// UI State
val currentDestination: NavDestination?
@Composable get() = navController
.currentBackStackEntryAsState().value?.destination
// UI logic
fun navigate(destination: NiaNavigationDestination, route: String? = null) { /* ... */ }
/* ... */
}
Yukarıdaki örnekte, NiaAppState
ile ilgili aşağıdaki ayrıntılar dikkat çekicidir:
- Yeniden oluşturma işleminden sonra kalmaz:
NiaAppState
,remembered
içinderememberNiaAppState
Compose adlandırma kurallarına uygun bir Composable işleviyle oluşturulur.Activity
Activity
yeniden oluşturulduktan sonra önceki örnek kaybolur ve tüm bağımlılıkları ile birlikte yeni bir örnek oluşturulur. Bu örnek, yeniden oluşturulanActivity
'nın yeni yapılandırmasına uygundur. Bu bağımlılıklar yeni olabilir veya önceki yapılandırmadan geri yüklenmiş olabilir. Örneğin,rememberNavController()
,NiaAppState
oluşturucusunda kullanılır veActivity
yeniden oluşturma işlemi sırasında durumu korumak içinrememberSaveable
'ye devreder. - Kullanıcı arayüzü kapsamlı veri kaynaklarına referanslar içeriyor:
navigationController
,Resources
ve benzer yaşam döngüsü kapsamlı türlere yapılan referanslar, aynı yaşam döngüsü kapsamını paylaştıkları içinNiaAppState
içinde güvenli bir şekilde tutulabilir.
Durum tutucu için ViewModel ve düz sınıf arasında seçim yapma
Önceki bölümlerde, ViewModel
ile düz sınıf durum tutucu arasında seçim yapma, kullanıcı arayüzü durumuna uygulanan mantığa ve mantığın üzerinde çalıştığı veri kaynaklarına bağlıdır.
Özetle, aşağıdaki şemada durum sahiplerinin kullanıcı arayüzündeki konumları gösterilmektedir. Durum oluşturma ardışık düzeni:

Sonuç olarak, kullanıcı arayüzü durumunu, kullanıldığı yere en yakın durum tutucuları kullanarak oluşturmalısınız. Daha az resmi bir ifadeyle, uygun sahipliği korurken durumu mümkün olduğunca düşük tutmanız gerekir. İşletme mantığına erişmeniz gerekiyorsa ve kullanıcı arayüzü durumunun, ekranlar arasında gezinme sırasında Activity
yeniden oluşturulsa bile korunması gerekiyorsa işletme mantığı durumu tutucunuzun uygulanması için ViewModel
harika bir seçimdir. Daha kısa ömürlü kullanıcı arayüzü durumu ve kullanıcı arayüzü mantığı için yaşam döngüsü yalnızca kullanıcı arayüzüne bağlı olan düz bir sınıf yeterli olmalıdır.
Durum bilgisi depolayıcılar birleştirilebilir
Durum sahipleri, bağımlılıklar eşit veya daha kısa bir kullanım ömrüne sahip olduğu sürece diğer durum sahiplerine bağlı olabilir. Buna örnek olarak şunlar verilebilir:
- Bir kullanıcı arayüzü mantığı durum koruyucusu, başka bir kullanıcı arayüzü mantığı durum koruyucusuna bağlı olabilir.
- Ekran düzeyindeki bir durum koruyucu, kullanıcı arayüzü mantığı durum koruyucusuna bağlı olabilir.
Aşağıdaki kod snippet'inde, Compose'un DrawerState
başka bir dahili durum tutucu olan SwipeableState
'ya nasıl bağlı olduğu ve bir uygulamanın kullanıcı arayüzü mantığı durum tutucusunun DrawerState
'ya nasıl bağlı olabileceği gösterilmektedir:
@Stable
class DrawerState(/* ... */) {
internal val swipeableState = SwipeableState(/* ... */)
// ...
}
@Stable
class MyAppState(
private val drawerState: DrawerState,
private val navController: NavHostController
) { /* ... */ }
@Composable
fun rememberMyAppState(
drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
navController: NavHostController = rememberNavController()
): MyAppState = remember(drawerState, navController) {
MyAppState(drawerState, navController)
}
Bir durum koruyucudan daha uzun süre yaşayan bağımlılık örneği, ekran düzeyindeki bir durum koruyucuya bağlı olan bir kullanıcı arayüzü mantığı durum koruyucusu olabilir. Bu durum, daha kısa ömürlü durum tutucunun yeniden kullanılabilirliğini azaltır ve durum tutucuya, aslında ihtiyaç duyduğundan daha fazla mantığa ve duruma erişim izni verir.
Daha kısa ömürlü durum tutucunun daha yüksek kapsamlı bir durum tutucudan belirli bilgilere ihtiyacı varsa durum tutucu örneğini iletmek yerine yalnızca ihtiyaç duyduğu bilgileri parametre olarak iletin. Örneğin, aşağıdaki kod snippet'inde, kullanıcı arayüzü mantığı durum tutucu sınıfı, bağımlılık olarak ViewModel'in tamamını iletmek yerine ViewModel'den parametre olarak yalnızca ihtiyacı olanları alır.
class MyScreenViewModel(/* ... */) {
val uiState: StateFlow<MyScreenUiState> = /* ... */
fun doSomething() { /* ... */ }
fun doAnotherThing() { /* ... */ }
// ...
}
@Stable
class MyScreenState(
// DO NOT pass a ViewModel instance to a plain state holder class
// private val viewModel: MyScreenViewModel,
// Instead, pass only what it needs as a dependency
private val someState: StateFlow<SomeState>,
private val doSomething: () -> Unit,
// Other UI-scoped types
private val scaffoldState: ScaffoldState
) {
/* ... */
}
@Composable
fun rememberMyScreenState(
someState: StateFlow<SomeState>,
doSomething: () -> Unit,
scaffoldState: ScaffoldState = rememberScaffoldState()
): MyScreenState = remember(someState, doSomething, scaffoldState) {
MyScreenState(someState, doSomething, scaffoldState)
}
@Composable
fun MyScreen(
modifier: Modifier = Modifier,
viewModel: MyScreenViewModel = viewModel(),
state: MyScreenState = rememberMyScreenState(
someState = viewModel.uiState.map { it.toSomeState() },
doSomething = viewModel::doSomething
),
// ...
) {
/* ... */
}
Aşağıdaki şema, kullanıcı arayüzü ile önceki kod snippet'indeki farklı durum sahipleri arasındaki bağımlılıkları gösterir:

Örnekler
Aşağıdaki Google örneklerinde, kullanıcı arayüzü katmanında durum tutucuların kullanımı gösterilmektedir. Bu rehberliğin uygulamadaki işleyişini görmek için bu kaynakları inceleyin:
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir.
- Kullanıcı arayüzü katmanı
- Kullanıcı arayüzü durumu üretimi
- Uygulama mimarisi kılavuzu