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