Kullanıcı arayüzü katmanı kılavuzunda, kullanıcı arayüzü katmanı için Kullanıcı Arayüzü Durumunu üretme ve yönetmenin bir yolu olarak tek yönlü veri akışı (UDF) açıklanmaktadır.
![Veri, veri katmanından kullanıcı arayüzüne tek yönlü olarak aktarılır.](https://developer.android.com/static/images/topic/architecture/ui-layer/udf.png?authuser=5&hl=tr)
Ayrıca, UDF yönetiminin delege olarak eyalet sahibi adı verilen özel bir sınıfa delege etmenin avantajlarını vurgular. Bir durum tutucuyu ViewModel
veya düz bir sınıf aracılığıyla uygulayabilirsiniz. Bu belgede, devlet sahipleri ve kullanıcı arayüzü
katmanında oynadıkları role yakından bakalım.
Bu belgenin sonunda, kullanıcı arayüzü katmanında uygulama durumunu nasıl yöneteceğinizi anlamış olmalısınız. Bu, kullanıcı arayüzü durumu üretim ardışık düzenidir. Aşağıdakileri anlayabilmeniz ve bilmeniz gerekir:
- Kullanıcı arayüzü katmanındaki kullanıcı arayüzü durumu türlerini anlayın.
- Kullanıcı arayüzü katmanındaki bu kullanıcı arayüzü durumları üzerinde çalışan mantık türlerini anlayın.
ViewModel
veya basit sınıf gibi bir eyalet sahibinin uygun uygulamasını nasıl seçeceğinizi öğrenin.
Kullanıcı arayüzü durumu üretim ardışık düzeninin öğeleri
Kullanıcı arayüzü durumu ve bunu oluşturan 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ü açıklayan özelliktir. İki tür kullanıcı arayüzü durumu vardır:
- Ekran kullanıcı arayüzü durumu, ekranda görüntülemeniz gereken ifadedir. Örneğin,
NewsUiState
sınıfı, kullanıcı arayüzünün oluşturulması için gereken haber makalelerini ve diğer bilgileri içerebilir. Bu durum, uygulama verileri içerdiğinden genellikle hiyerarşinin diğer katmanlarıyla bağlantılıdır. - Kullanıcı arayüzü öğesi durumu, oluşturulma şeklini etkileyen kullanıcı arayüzü öğelerinin yapısında olan özellikleri ifade eder. Bir kullanıcı arayüzü öğesi gösterilebilir veya gizlenebilir ve belirli bir yazı tipi, yazı tipi boyutu veya yazı tipi rengine sahip olabilir. Doğası gereği durum bilgili olduğundan, Android Görünümleri'nde durumu değiştirmek veya sorgulamak için yöntem sunan Görünüm ise bu durumu yönetir. Buna örnek olarak, metni için
TextView
sınıfınınget
veset
yöntemleri verilebilir. JetpackCompose'da durum, composable'ın dışındadır ve hatta composable'ın yakın çevresinden çağrıda bulunan composable işlevine veya durum sahibine de kaldırılabilir.Scaffold
composable içinScaffoldState
bu şekilde bir örnektir.
Mantık
Uygulama verileri ve kullanıcı etkinlikleri, kullanıcı arayüzü durumunun zamanla değişmesine neden olduğundan kullanıcı arayüzü durumu statik bir özellik değildir. Mantık, değişiklik ayrıntılarını (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 dahil) belirler.
![Mantık, kullanıcı arayüzü durumu üretir](https://developer.android.com/static/images/topic/architecture/ui-layer/logic.png?authuser=5&hl=tr)
Bir uygulamadaki mantık, iş mantığı veya kullanıcı arayüzü mantığı olabilir:
- İş mantığı, uygulama verilerine yönelik ürün şartlarının uygulanmasıdır. Örneğin, kullanıcı düğmeye dokunduğunda haber okuyucu uygulamasında makaleye yer işareti koyma. Bir yer işaretini bir dosyaya veya veritabanına kaydetmeye yönelik bu mantık genellikle alana ya da veri katmanlarına yerleştirilir. Eyalet sahibi genellikle ortaya koyduğu yöntemleri çağırarak bu mantığı bu katmanlara delege eder.
- Kullanıcı arayüzü mantığı, ekranda kullanıcı arayüzü durumunun nasıl gösterileceğiyle ilgilidir. Örneğin, kullanıcı bir kategori seçtiğinde doğru arama çubuğu ipucunu almak, listedeki belirli bir öğeye gitmek veya kullanıcı bir düğmeyi tıkladığında belirli bir ekrana gitmek için gezinme mantığını kullanmak.
Android yaşam döngüsü ile kullanıcı arayüzü durumu ve mantığı türleri
Kullanıcı arayüzü katmanı, biri bağımlı, diğeri kullanıcı arayüzü yaşam döngüsünden bağımsız olmak üzere iki bölümden oluşur. Bu ayırma, her bir bölümde kullanılabilecek veri kaynaklarını belirler ve bu nedenle farklı kullanıcı arayüzü durumu ve mantığı türleri gerektirir.
- Kullanıcı arayüzü yaşam döngüsünden bağımsız: Kullanıcı arayüzü katmanının bu bölümü, uygulamanın veri üreten katmanlarıyla (veri veya alan katmanları) ele alınır ve iş mantığıyla tanımlanır. Yaşam döngüsü, yapılandırma değişiklikleri ve kullanıcı arayüzünde
Activity
yeniden oluşturma işlemi, kullanıcı arayüzü durumu üretim ardışık düzeninin etkin olup olmadığını etkileyebilir ancak üretilen verilerin geçerliliğini etkilemez. - Kullanıcı arayüzü yaşam döngüsüne bağlıdır: Kullanıcı arayüzü katmanının bu bölümü, kullanıcı arayüzü mantığıyla ilgilidir ve yaşam döngüsünden veya 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. Sonuç olarak, durum 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ı alma, bu tür içeriklere örnek olarak verilebilir.
Yukarıdakiler, aşağıdaki tabloyla özetlenebilir:
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 ardışık düzeni, kullanıcı arayüzü durumu üretmek için atılan adımları ifade eder. Bu adımlar, daha önce tanımlanan mantık türlerinin uygulanmasını kapsar ve tamamen kullanıcı arayüzünüzün ihtiyaçlarına bağlıdır. Bazı kullanıcı arayüzleri, ardışık düzenin hem UI Yaşam Döngüsü'nden bağımsız hem de Kullanıcı Arayüzü Yaşam Döngüsü'ne bağlı bölümlerin her ikisinden de yararlanabilir veya hiçbirini kullanmayabilir.
Yani kullanıcı arayüzü katmanı ardışık düzeninin aşağıdaki permütasyonları geçerlidir:
Kullanıcı arayüzü durumu, kullanıcı arayüzü tarafından oluşturulur 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 başına atlamasına 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ü. Ekranda geçerli 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örüntülemek ü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 üretim ardışık düzenine her iki mantığın da uygulandığı durumlarda, kullanıcı arayüzü mantığından önce her zaman iş mantığı 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ürlerine ve bunların durum sahiplerine ayrıntılı bir bakış üzerinden bunun neden bir sorun olduğu ele alınmaktadır.
![Veri, veri üretme katmanından kullanıcı arayüzüne aktarılır](https://developer.android.com/static/images/topic/architecture/ui-layer/logic-hierarchy.png?authuser=5&hl=tr)
Devlet sahipleri ve sorumlulukları
Eyalet sahiplerinin sorumluluğu, uygulamanın okuyabilmesi için durumu depolamaktır. Mantığın gerekli olduğu durumlarda, bir aracı işlevi görür ve gerekli mantığı barındıran veri kaynaklarına erişim sağlar. Bu şekilde eyalet sahibi, mantığı uygun veri kaynağına delege eder.
Bunun sonucunda da şu faydalar elde edilir:
- 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ünün kendisi değiştirilmeden tekrarlanabilir.
- Test edilebilirlik: Kullanıcı arayüzü ve durum üretim mantığı bağımsız olarak test edilebilir.
- Okunabilirlik: Kodun okuyucuları, kullanıcı arayüzü sunu kodu ile kullanıcı arayüzü durumu üretim kodu arasındaki farklılıkları net bir şekilde görebilir.
Boyutu veya kapsamı ne olursa olsun her kullanıcı arayüzü öğesinin, karşılık gelen durum sahibiyle bire bir ilişkisi vardır. Ayrıca, bir durum sahibi, kullanıcı arayüzü durumu değişikliğiyle sonuçlanabilecek herhangi bir kullanıcı işlemini kabul edip işleyebilmeli ve sonrasında gelen durum değişikliğini gerçekleştirebilmelidir.
Eyalet sahiplerinin türleri
Kullanıcı arayüzü durumu ve mantığı türlerine 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 sahibi vardır:
- İş mantığı durum tutucusu.
- Kullanıcı arayüzü mantığı durum tutucusu.
Aşağıdaki bölümlerde, iş mantığı durumu sahibinden başlayarak devlet sahiplerinin türlerine daha yakından bakılmaktadır.
İş mantığı ve durum sahibi
İş mantığı durumu sahipleri, kullanıcı etkinliklerini işler ve verileri veri veya alan katmanlarından ekran kullanıcı arayüzü durumuna dönüştürür. Android yaşam döngüsü ve uygulama yapılandırması değişikliklerini değerlendirirken en iyi kullanıcı deneyimini sunmak için iş mantığından yararlanan devlet sahiplerinin aşağıdaki özelliklere sahip olması gerekir:
Özellik | Ayrıntı |
---|---|
Kullanıcı Arayüzü Durumu oluşturur | İş mantığı durumu sahipleri, kullanıcı arayüzleri için kullanıcı arayüzü durumunu oluşturmaktan sorumludur. Bu kullanıcı arayüzü durumu, genellikle kullanıcı etkinliklerinin işlenmesinin ve alan ile veri katmanlarından gelen verilerin okunmasının bir sonucudur. |
Rekreasyon aktivitesiyle elde tutulan içerik | İş mantığı durumu sahipleri, Activity yeniden oluşturma işleminde durum ve durum işleme ardışık düzenlerini koruyarak sorunsuz bir kullanıcı deneyimi sunmaya yardımcı olur. Devlet sahibinin tutulamadığı ve yeniden oluşturulduğu (genellikle sürecin ölümünden sonra) durumlarda, devlet sahibinin tutarlı bir kullanıcı deneyimi sağlamak için son durumunu kolayca yeniden oluşturabilmesi gerekir. |
Uzun ömürlü olma | İş mantığı durum sahipleri genellikle navigasyon hedeflerinin durumunu yönetmek için kullanılır. Bunun sonucunda, genellikle gezinme grafiğinden kaldırılana kadar gezinme değişikliklerindeki durumlarını korurlar. |
Kullanıcı arayüzüne özeldir ve yeniden kullanılamaz | İş mantığı durumu sahipleri, genellikle TaskEditViewModel veya TaskListViewModel gibi belirli bir uygulama işlevi için durum oluşturur ve dolayısıyla yalnızca bu uygulama işlevinde geçerlidir. Aynı eyalet sahibi, farklı form faktörlerinde bu uygulama işlevlerini destekleyebilir. Örneğin, uygulamanın mobil, TV ve tablet sürümleri aynı iş mantığı durumu tutucusunu yeniden kullanabilir. |
Örneğin, "Now in Android" uygulamasındaki yazar gezinme hedefini düşünün:
![Now in Android uygulaması, önemli bir uygulama işlevini temsil eden gezinme hedefinin kendi benzersiz iş mantığı durum sahibine nasıl sahip olması gerektiğini gösterir.](https://developer.android.com/static/images/topic/architecture/ui-layer/nia-author.png?authuser=5&hl=tr)
İş mantığı durum tutucusu olarak 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ğuna dikkat edin:
Özellik | Ayrıntı |
---|---|
AuthorScreenUiState üretir |
AuthorViewModel , AuthorsRepository ve NewsRepository kaynaklı verileri okur ve bu verileri kullanarak AuthorScreenUiState üretir. Kullanıcı, AuthorsRepository adlı kullanıcıya yetki vererek Author sayfasını takip etmek veya takibi bırakmak istediğinde de iş mantığına uyar. |
Veri katmanına erişimi var | AuthorsRepository ve NewsRepository örnekleri, oluşturucusunda buna iletilir. Bu sayede, Author aşağıdaki iş mantığını uygulayabilir. |
Activity yeniden etkinlikten sonra hayatta kalır |
ViewModel ile uygulandığından hızlı Activity yeniden oluşturma işleminde tutulur. İşlemin ölümü durumunda, veri katmanından kullanıcı arayüzü durumunu geri yüklemek için gereken minimum miktarda bilginin sağlanması amacıyla SavedStateHandle nesnesi okunabilir. |
Uzun ömürlü bir yaşam sürdürüyor | ViewModel , gezinme grafiğine dahil edilir. Bu nedenle, yazar hedefi gezinme grafiğinden kaldırılmadığı sürece uiState StateFlow içindeki kullanıcı arayüzü durumu bellekte kalır. Durum yalnızca kullanıcı arayüzü durumunun toplayıcısı varsa üretildiğinden, StateFlow kullanılması, durum tembelliğine neden olan iş mantığının uygulanmasını da sağlar. |
Kullanıcı arayüzüne özgü olmalıdır | AuthorViewModel yalnızca yazar gezinme hedefi için geçerlidir ve başka bir yerde tekrar kullanılamaz. Gezinme hedeflerinde yeniden kullanılan herhangi bir iş mantığı varsa bu iş mantığı, veri veya alan katmanı kapsamlı bir bileşene dahil edilmelidir. |
İş mantığı durum sahibi olarak ViewModel
Android geliştirmede ViewModels'in avantajları, bunları iş mantığına erişim sağlamak ve uygulama verilerini ekranda sunum için hazırlamak üzere uygun hale getirir. Bu avantajlar arasında şunlar yer alır:
- ViewModelleri tarafından tetiklenen işlemler, yapılandırma değişikliklerinden sonra da yürürlükte kalır.
- Gezinme ile entegrasyon:
- Gezinme, ekran arka yığındayken ViewModel'leri önbelleğe alır. Önceden yüklediğiniz verilerin, hedefinize döndüğünüzde anında kullanılabilir olması açısından bu önemlidir. Bu işlemi, composable ekranın yaşam döngüsünü takip eden bir durum sahibiyle yapmak daha zordur.
- ViewModel, hedef arka yığından çıkarıldığında da temizlenir. Böylece, durumunuz otomatik olarak temizlenir. Bu, yapılandırma değişikliğinden veya başka sebeplerden dolayı yeni ekrana gitme gibi birden fazla sebeple gerçekleşebilecek composable'ın atılmasını dinlemekten farklıdır.
- Hilt gibi diğer Jetpack kitaplıklarıyla entegrasyon.
Kullanıcı arayüzü mantığı ve durum tutucu
Kullanıcı arayüzü mantığı, kullanıcı arayüzünün sağladığı veriler üzerinde çalışan bir mantıktır. Bu işlem, kullanıcı arayüzü öğelerinin durumunda veya allow API ya da Resources
gibi kullanıcı arayüzü veri kaynaklarında olabilir. Kullanıcı arayüzü mantığından yararlanan devlet sahipleri genellikle aşağıdaki özelliklere sahiptir:
- Kullanıcı arayüzü durumunu oluşturur ve kullanıcı arayüzü öğelerinin durumunu yönetir.
Activity
yeniden oluşturmasından sonra devam etmez: Kullanıcı arayüzü mantığında barındırılan durum sahipleri, genellikle kullanıcı arayüzünün kendisinden veri kaynaklarına bağlıdır ve yapılandırma değişiklikleri genelinde bu bilgileri saklamaya çalışmak, bellek sızıntısına neden olmamasına kıyasla daha sık karşılaşılan bir durumdur. Devlet sahiplerinin yapılandırma değişiklikleri sırasında verilere sahip olmaları gerekiyorsa,Activity
rekreasyon ortamında hayatta kalmaya daha uygun olan başka bir bileşene yetki vermeleri gerekir. Örneğin Jetpack Compose'daremembered
işlevleriyle oluşturulan Oluşturulabilir kullanıcı arayüzü öğesi durumları,Activity
yeniden oluşturmalarında durumu korumak için genelliklerememberSaveable
öğesine yetki verir. Bu tür işlevlere örnek olarakrememberScaffoldState()
verememberLazyListState()
verilebilir.- Kullanıcı arayüzü kapsamlı veri kaynaklarına referanslar içeriyor: Kullanıcı arayüzü mantık durumu tutucusu, kullanıcı arayüzüyle aynı yaşam döngüsüne sahip olduğundan, yaşam döngüsü API'leri ve Kaynakları gibi veri kaynaklarına güvenli bir şekilde başvurulabilir ve okunabilir.
- Birden fazla kullanıcı arayüzünde yeniden kullanılabilir olması: Aynı kullanıcı arayüzü mantık durumu tutucusunun farklı örnekleri, uygulamanın farklı bölümlerinde yeniden kullanılabilir. Örneğin, bir çip grubunun kullanıcı girişi etkinliklerini yönetmek için kullanılan durum tutucu, filtre çipleri için arama sayfasında ve e-postanın alıcıları için "kime" alanında kullanılabilir.
Kullanıcı arayüzü mantık durumu tutucusu genellikle düz bir sınıfla uygulanır. Bunun nedeni, kullanıcı arayüzü mantığı durumu tutucusunun oluşturulmasından kullanıcı arayüzünün sorumlu olması ve kullanıcı arayüzü mantığı durumu tutucusunun, kullanıcı arayüzüyle aynı yaşam döngüsüne sahip olmasıdır. Örneğin Jetpack Compose'da durum sahibi Beste'nin bir parçasıdır ve Beste'nin yaşam döngüsünü takip eder.
Bu, yukarıdaki Now in Android örneğinde bulunan aşağıdaki örnekte açıklanabilir:
![Artık Android'de, kullanıcı arayüzü mantığını yönetmek için düz bir sınıf durumu tutucu kullanılır.](https://developer.android.com/static/images/topic/architecture/ui-layer/nia-home.png?authuser=5&hl=tr)
Android'de Now örneği, cihazın ekran boyutuna bağlı olarak, gezinme için bir alt uygulama çubuğunu veya bir gezinme çubuğunu gösterir. Küçük ekranlarda alt uygulama çubuğu, daha büyük ekranlarda ise gezinme çubuğu 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ı bir 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:
Activity
yeniden oluşturmada hayatta kalamaz:NiaAppState
, Oluştur adlandırma kurallarına göre bir Oluşturulabilir işlevirememberNiaAppState
kullanılarak bestederemembered
olarak yer alıyor.Activity
yeniden oluşturulduktan sonra önceki örnek kaybedilir ve yeniden oluşturulanActivity
öğesinin yeni yapılandırmasına uygun, tüm bağımlılıkları iletilmiş yeni bir örnek oluşturulur. Bu bağımlılıklar yeni veya önceki yapılandırmadan geri yüklenebilir. ÖrneğinrememberNavController()
,NiaAppState
oluşturucuda kullanılır veActivity
yeniden oluşturma genelinde durumu korumak içinrememberSaveable
adlı kullanıcıya yetki verir.- Kullanıcı arayüzü kapsamlı veri kaynaklarına referanslar içeriyor: Aynı yaşam döngüsü kapsamını paylaştıkları için
navigationController
,Resources
ve diğer benzer yaşam döngüsü kapsamlı türlere yapılan referanslarNiaAppState
içinde güvenle tutulabilir.
Durum sahibi için ViewModel ve düz sınıf arasında seçim yapma
Yukarıdaki bölümlerde, ViewModel
ile düz sınıf durum tutucu arasında seçim yapmak, kullanıcı arayüzü durumuna uygulanan mantık ve mantığın üzerinde çalıştığı veri kaynakları ile ilgilidir.
Özet olarak aşağıdaki şemada, kullanıcı arayüzü durumu üretim hattındaki durum sahiplerinin konumu gösterilmektedir:
![Veri üretme katmanından kullanıcı arayüzü katmanına veri akışı](https://developer.android.com/static/images/topic/architecture/ui-layer/stateholder-hierarchy.png?authuser=5&hl=tr)
Sonuç olarak, kullanıcı arayüzü durumunu, tüketildiği yere en yakın durum sahiplerini kullanarak oluşturmanız gerekir. Daha resmî olmayan bir biçimde, durumu mümkün olduğunca
düşük tutmalı ve uygun sahipliği korumalısınız. İş mantığına erişmeniz ve Activity
yeniden oluşturma sürecinde bile bir ekrana geçilebildiği sürece kullanıcı arayüzü durumunun devam etmesi gerekiyorsa ViewModel
, iş mantığı durumu tutucu uygulamanız için ideal bir seçenektir. 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 sade bir sınıf yeterli olacaktır.
Eyalet sahipleri birleştirilebilir
Bağımlılıkların ömürleri eşit veya daha kısa olduğu sürece devlet sahipleri, diğer devlet sahiplerine güvenebilirler. Bu tür içeriğe ilişkin bazı örnekler:
- bir kullanıcı arayüzü mantık durumu tutucusu başka bir kullanıcı arayüzü mantık durumu sahibine bağlı olabilir.
- ekran düzeyi durum tutucusu, bir kullanıcı arayüzü mantık durumu sahibine bağlı olabilir.
Aşağıdaki kod snippet'i, Compose'un DrawerState
öğesinin başka bir dahili durum sahibine (SwipeableState
) nasıl bağlı olduğunu ve bir uygulamanın kullanıcı arayüzü mantık durumu sahibinin DrawerState
öğesine nasıl bağlı olabileceğini göstermektedir:
@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 tutucunun geçerlilik süresi sona eren bağımlılıklara örnek olarak ekran düzeyi durum sahibine bağlı bir kullanıcı arayüzü mantık durumu tutucusu verilebilir. Bu, daha kısa ömürlü durum sahibinin tekrar kullanılabilirliğini azaltıp gerçekte gerektirdiğinden daha fazla mantık ve duruma erişmesini sağlar.
Daha kısa ömürlü durum sahibi, daha yüksek kapsamlı bir durum sahibinden gelen belirli bilgilere ihtiyaç duyuyorsa durum sahibi ö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ık durum tutucu sınıfı, ViewModel örneğinin tamamını bağımlılık olarak iletmek yerine, tam olarak ihtiyacı olan şeyi ViewModel'den parametre olarak 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 şemada, kullanıcı arayüzü ile önceki kod snippet'inin farklı durum sahipleri arasındaki bağımlılıklar gösterilmektedir:
![Hem kullanıcı arayüzü mantık durumu sahibine hem de ekran düzeyi durum sahibine bağlı olarak kullanıcı arayüzü](https://developer.android.com/static/images/topic/architecture/ui-layer/stateholder-dependencies.png?authuser=5&hl=tr)
Numuneler
Aşağıdaki Google örnekleri, kullanıcı arayüzü katmanında durum sahiplerinin kullanımını göstermektedir. Uygulamadaki bu rehberliği görmek için bu yöntemleri 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 rehberi