Eyaletinizin nereye tırmanıldığına ve gerekli mantığa bağlı olarak, kullanıcı arayüzü durumunuzu depolamak ve geri yüklemek için farklı API'ler kullanabilir. Her uygulama bir API kombinasyonundan yararlanmanız gerekir.
Etkinlik veya işlem nedeniyle tüm Android uygulamaları kullanıcı arayüzü durumunu kaybedebilir rekreasyon. Bu durum kaybı aşağıdaki olaylardan kaynaklanabilir:
- Yapılandırma değişiklikleri. Etkinlik kaldırılır ve yapılandırma değişiklikleri manuel olarak işlenir.
- Sistem tarafından başlatılan işlem ölümü. Uygulama arka planda çalışıyor ve cihaz, diğer işlemler tarafından kullanılacak kaynakları (bellek gibi) serbest bırakır.
Pozitif kullanıcılar için, bu olaylardan sonra durumu korumak büyük önem taşır. sahip olacaksınız. Hangi durumun kalıcı olacağını seçmek, uygulamanızın benzersiz kullanıcısına bağlıdır akış gösterir. En iyi uygulama olarak en azından kullanıcı girişini korumalı ve gezinmeyle ilgili durumu gösterir. Örneğin, bir kullanıcının hakkında daha fazla bilgi istediği öğenin kimliği, devam etmekte olan kullanıcı tercihlerini belirleme veya metin alanlarına giriş yapma.
Bu sayfada, kullanıcı arayüzü durumunun nereye bağlı olduğuna bağlı olarak depolanabilecek API'ler ve bunu gerektiren mantığa göre hareket etmeniz gerekir.
Kullanıcı arayüzü mantığı
Durumunuz kullanıcı arayüzüne composable işlevlerde veya yalın
Beste'ye dahil edilen durum sahibi sınıfları için
Etkinlik ve yeniden oluşturma işlemleri genelinde durumu korumak için rememberSaveable.
Aşağıdaki snippet'te rememberSaveable tek bir boole değerini depolamak için kullanılır
Kullanıcı arayüzü öğesi durumu:
@Composable fun ChatBubble( message: Message ) { var showDetails by rememberSaveable { mutableStateOf(false) } ClickableText( text = AnnotatedString(message.content), onClick = { showDetails = !showDetails } ) if (showDetails) { Text(message.timestamp) } }
showDetails, sohbet balonu daraltıldığında depolayan bir boole değişkenidir
veya genişletildi.
rememberSaveable, kullanıcı arayüzü öğesi durumunuBundle
kaydedilen örnek durumu mekanizmasını ifade eder.
Temel türleri pakete otomatik olarak depolayabilir. Bulunduğunuz eyalet
veri sınıfı gibi temel olmayan bir türde tutulursa,
Parcelize ek açıklamasını kullanma gibi farklı depolama mekanizmaları
listSaver ve mapSaver gibi Compose API'leri kullanarak veya
Oluşturma çalışma zamanı Saver sınıfını genişleten özel tasarruf sınıfı. Bkz. Yollar
mağaza durumu dokümanlarını inceleyin.
Aşağıdaki snippet'te rememberLazyListState Oluştur
Bir reklam öğesinin kaydırma durumundan oluşan LazyListState API depoları
LazyColumn veya LazyRow, rememberSaveable kullanarak. Bir
LazyListState.Saver adlı özel koruyucu şunları yapabilir:
saklamayı ve kaydırma durumunu geri yüklemeyi sağlar. Bir etkinlikten ya da yeniden değerlendirme sürecinden sonra (örneğin,
cihaz yönünü değiştirme gibi bir yapılandırma değişikliğinden sonra,
korunduğundan emin olun.
@Composable fun rememberLazyListState( initialFirstVisibleItemIndex: Int = 0, initialFirstVisibleItemScrollOffset: Int = 0 ): LazyListState { return rememberSaveable(saver = LazyListState.Saver) { LazyListState( initialFirstVisibleItemIndex, initialFirstVisibleItemScrollOffset ) } }
En iyi uygulama
rememberSaveable, kullanıcı arayüzü durumunu depolamak için bir Bundle kullanır. Bu durum
aynı zamanda veri yazan diğer API'ler (örneğin, onSaveInstanceState()
yararlı olabilir. Ancak, bu Bundle cihazın boyutu sınırlıdır ve bu öğe için
nesneleri çalışma zamanında TransactionTooLarge istisnaya neden olabilir. Bu
özellikle, aynı öğenin tek bir Activity uygulamasında da
Bundle uygulama genelinde kullanılıyor.
Bu tür kilitlenmeleri önlemek için büyük boyutlu karmaşık nesneleri veya listesidir.
Bunun yerine, gerekli olan minimum durumu (kimlikler veya anahtarlar gibi) depolayın ve bunları kullanarak kalıcı kullanıcı arayüzü gibi diğer mekanizmalara geri yükleme yetkisi depolama alanı.
Bu tasarım seçimleri uygulamanızın belirli kullanım alanlarına ve uygulamanızın nasıl davranmasını bekliyorlar?
Eyalet geri yükleme işlemini doğrulayın
rememberSaveable ile depolanan durumun
Etkinlik veya işlem şu durumlarda olduğunda öğe oluşturma öğeleri doğru şekilde geri yüklenir:
yeniden oluşturulmuş. Bunu başarmak için kullanılabilecek bazı API'ler vardır:
StateRestorationTester. Aşağıdakileri yapmak için Test dokümanlarını inceleyin:
daha fazla bilgi edinin.
İş mantığı
Kullanıcı arayüzü öğesi durumunuz,ViewModel
iş mantığının gerektirdiği şekilde ViewModel API'lerini kullanabilirsiniz.
Android uygulamanızda ViewModel kullanmanın temel avantajlarından biri
Google Analytics 4'te tarama yapar. Bir yapılandırma olduğunda
etkinlik kaldırılır ve yeniden oluşturulursa, kullanıcı arayüzü durumu
ViewModel bellekte tutulur. Etkinlikten sonra eski ViewModel
ekli olduğundan emin olun.
Ancak ViewModel örneği, sistem tarafından başlatılan işlem ölümünden sonra da devam edemez.
Kullanıcı arayüzü durumunun hayatta kalması için
ViewModel, SavedStateHandle API'yi içerir.
En iyi uygulama
SavedStateHandle, kullanıcı arayüzü durumunu depolamak için Bundle mekanizmasını da kullanır. Bu nedenle,
bunu yalnızca basit kullanıcı arayüzü öğesi durumunu depolamak için kullanmalısınız.
İş kurallarının uygulanması ve erişilmesiyle oluşturulan ekran kullanıcı arayüzü durumu
uygulamanızın kullanıcı arayüzü dışındaki katmanlarının
Olası karmaşıklığı ve boyutu nedeniyle SavedStateHandle. Tekliflerinizi otomatikleştirmek ve optimize etmek için
karmaşık veya büyük verileri depolamak için farklı mekanizmalar (ör. yerel kalıcı
depolama alanı. Süreç yeniden oluşturma işleminden sonra ekran,
SavedStateHandle içinde depolanan, geri yüklenen geçici durumu (varsa) ve
ekran kullanıcı arayüzü durumu, veri katmanından tekrar oluşturulur.
SavedStateHandle API
SavedStateHandle, kullanıcı arayüzü öğesi durumunu depolamak için farklı API'lere sahiptir. Çoğu
son derece önemli:
Oluştur State |
saveable() |
|---|---|
StateFlow |
getStateFlow() |
Oluştur: State
Kullanıcı arayüzü öğesini okumak ve yazmak için SavedStateHandle ürününün saveable API'sini kullanın
MutableState olarak görünür, böylece etkinlikten çıkar ve yeniden oluşturma işlemini
çok az kod kurulumu gerekir.
saveable API, kullanıma hazır temel türleri destekler ve
rememberSaveable() gibi özel koruyucular kullanmak için stateSaver parametresini kullanın.
Aşağıdaki snippet'te message, kullanıcı girişi türlerini bir
TextField:
class ConversationViewModel( savedStateHandle: SavedStateHandle ) : ViewModel() { var message by savedStateHandle.saveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) } private set fun update(newMessage: TextFieldValue) { message = newMessage } /*...*/ } val viewModel = ConversationViewModel(SavedStateHandle()) @Composable fun UserInput(/*...*/) { TextField( value = viewModel.message, onValueChange = { viewModel.update(it) } ) }
Aşağıdakiler hakkında daha fazla bilgi için SavedStateHandle dokümanlarına bakın:
(saveable API'yi kullanarak) hakkında daha fazla bilgi edinin.
StateFlow
Kullanıcı arayüzü öğesi durumunu depolamak ve bir akış olarak kullanmak için getStateFlow() kullanın
SavedStateHandle. StateFlow okundu
ve API yalnızca bir anahtar belirtmenizi gerektirir. Böylece, akışı
yeni bir değer oluşturabilirsiniz. Yapılandırdığınız anahtarla StateFlow öğesini alabilirsiniz
ve en son değeri toplayın.
Aşağıdaki snippet'te savedFilterType, bir StateFlow değişkenidir
bir sohbet uygulamasında sohbet kanalları listesine uygulanan bir filtre türü depolar:
private const val CHANNEL_FILTER_SAVED_STATE_KEY = "ChannelFilterKey" class ChannelViewModel( channelsRepository: ChannelsRepository, private val savedStateHandle: SavedStateHandle ) : ViewModel() { private val savedFilterType: StateFlow<ChannelsFilterType> = savedStateHandle.getStateFlow( key = CHANNEL_FILTER_SAVED_STATE_KEY, initialValue = ChannelsFilterType.ALL_CHANNELS ) private val filteredChannels: Flow<List<Channel>> = combine(channelsRepository.getAll(), savedFilterType) { channels, type -> filter(channels, type) }.onStart { emit(emptyList()) } fun setFiltering(requestType: ChannelsFilterType) { savedStateHandle[CHANNEL_FILTER_SAVED_STATE_KEY] = requestType } /*...*/ } enum class ChannelsFilterType { ALL_CHANNELS, RECENT_CHANNELS, ARCHIVED_CHANNELS }
Kullanıcı her yeni filtre türü seçtiğinde setFiltering çağrılır. Bu
anahtarla saklanan SavedStateHandle işlevinde yeni bir değer kaydeder
_CHANNEL_FILTER_SAVED_STATE_KEY_. savedFilterType,
anahtara depolanan en son değer. filteredChannels şu akışa abone:
veya kanal filtreleme
yöntemini kullanmak.
Şu konular hakkında daha fazla bilgi için SavedStateHandle dokümanlarına göz atın:
getStateFlow() API.
Özet
Aşağıdaki tabloda, bu bölümde ele alınan API'ler ve ne zaman kullanılmaları gerektiği özetlenmiştir. kullanıcı arayüzü durumunu kaydetmek için:
| Etkinlik | Kullanıcı arayüzü mantığı | ViewModel içinde iş mantığı |
|---|---|---|
| Yapılandırma değişiklikleri | rememberSaveable |
Otomatik |
| Sistem tarafından başlatılan işlem ölümü | rememberSaveable |
SavedStateHandle |
Kullanılacak API, eyaletin nerede bulunduğuna ve bu eyaletin
gerekiyor. Kullanıcı arayüzü mantığında kullanılan durum için rememberSaveable değerini kullanın. Örneğin,
iş mantığı için kullanılan bir ifadedir (ViewModel içinde tutarsanız,
SavedStateHandle kullanarak kaydedebilirsiniz.
Paket API'lerini (rememberSaveable ve SavedStateHandle) şu amaçlarla kullanmalısınız:
kullanıcı arayüzü durumunu depolama. Bu veriler, geri yüklenmesi için gereken minimum veri miktarıdır
diğer depolama mekanizmalarıyla birlikte kullanıcı arayüzünü önceki durumuna geri döndürür. Örneğin,
Örneğin, kullanıcının baktığı bir profilin kimliğini pakette saklarsanız
profil ayrıntıları gibi ağır verileri veri katmanından getirebilirsiniz.
Kullanıcı arayüzü durumunu kaydetmenin farklı yolları hakkında daha fazla bilgi için genel Kullanıcı Arayüzü Durumu belgelerini ve veri katmanı sayfasını inceleyebilirsiniz.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Kaldırılacak bölge durumu
- State ve Jetpack Compose
- Listeler ve ızgaralar