Sayfalandırma kitaplığı, sayfalandırılmış veriler için yükleme isteklerinin durumunu izler ve
LoadState sınıfıyla karşılaştırabilirsiniz.
Uygulamanız,
PagingDataAdapter -
geçerli durumla ilgili bilgi alıp kullanıcı arayüzünü buna göre güncelleyin. Bu
durumları, kullanıcı arayüzüyle eşzamanlı olduğundan bağdaştırıcıdan sağlanır.
Bu, sayfa yükleme işlemi tamamlandığında dinleyicinizin güncellemeleri aldığı anlamına gelir.
uygulanmıştır.
Her biri için ayrı bir LoadState sinyali sağlanır
LoadType ve veri kaynağı türü
(PagingSource veya
RemoteMediator) bulabilirsiniz. İlgili içeriği oluşturmak için kullanılan
CombinedLoadStates
dinleyici tarafından sağlanan nesne, yükleme durumu hakkında bilgi sağlar
tüm bu sinyallerden yararlanır. Bu ayrıntılı bilgileri kullanarak
ilgili yükleme göstergeleri sunun.
Durumlar yükleniyor
Sayfalandırma kitaplığı, yükleme durumunu
LoadState nesne algılandı. LoadState nesne bağlı olarak üç biçimden birini alır
mevcut yükleme durumu:
- Etkin bir yükleme işlemi ve hata yoksa
LoadStatebirLoadState.NotLoadingnesnesini tanımlayın. Bu alt sınıf şunları da içerir:endOfPaginationReachedözelliğinin değeri. - Etkin bir yükleme işlemi varsa
LoadState,LoadState.Loadingnesnesini tanımlayın. - Hata varsa
LoadState,LoadState.Errornesnesini ifade eder.
LoadState öğesini kullanıcı arayüzünüzde iki şekilde kullanabilirsiniz: bir işleyici veya
yükleme durumunu doğrudan
RecyclerView
liste'ye dokunun.
İşleyiciyle yükleme durumuna erişme
Kullanıcı arayüzünüzde genel kullanım için yükleme durumunu öğrenmek üzere
loadStateFlow
akış veya
addLoadStateListener()
yöntemi (PagingDataAdapter) tarafından sağlanır. Bu mekanizmalar
LoadState hakkında bilgi içeren bir CombinedLoadStates nesnesi
ayrı ayrı belirleyebilirsiniz.
Aşağıdaki örnekte, PagingDataAdapter farklı bir kullanıcı arayüzü gösteriyor
yenilenme yükünün mevcut durumuna bağlı olarak farklılık gösterir:
Kotlin
// Activities can use lifecycleScope directly, but Fragments should instead use // viewLifecycleOwner.lifecycleScope. lifecycleScope.launch { pagingAdapter.loadStateFlow.collectLatest { loadStates -> progressBar.isVisible = loadStates.refresh is LoadState.Loading retry.isVisible = loadState.refresh !is LoadState.Loading errorMsg.isVisible = loadState.refresh is LoadState.Error } }
Java
pagingAdapter.addLoadStateListener(loadStates -> { progressBar.setVisibility(loadStates.refresh instanceof LoadState.Loading ? View.VISIBLE : View.GONE); retry.setVisibility(loadStates.refresh instanceof LoadState.Loading ? View.GONE : View.VISIBLE); errorMsg.setVisibility(loadStates.refresh instanceof LoadState.Error ? View.VISIBLE : View.GONE); });
Java
pagingAdapter.addLoadStateListener(loadStates -> { progressBar.setVisibility(loadStates.refresh instanceof LoadState.Loading ? View.VISIBLE : View.GONE); retry.setVisibility(loadStates.refresh instanceof LoadState.Loading ? View.GONE : View.VISIBLE); errorMsg.setVisibility(loadStates.refresh instanceof LoadState.Error ? View.VISIBLE : View.GONE); });
CombinedLoadStates hakkında daha fazla bilgi için bkz. Ek yüklemeye erişim
eyalet bilgilerini kontrol edin.
Yükleme durumunu bağdaştırıcıyla sunma
Sayfalama kitaplığı,
Şu için LoadStateAdapter:
bunun amacı, sayfalandırılmış görüntülenen listede doğrudan yükleme durumunu sunma
dışı verilerdir. Bu bağdaştırıcı, listenin mevcut yükleme durumuna erişim sağlar.
bilgileri görüntüleyen özel bir görünüm tutucuya geçirebilirsiniz.
Öncelikle, yükleme ve hataya verilen referansları tutan bir görünüm tutucu sınıfı oluşturun
kaç kez görüntülendiğini gösterir. Şu olarak LoadState kabul eden bir bind() işlevi oluşturun:
parametresinden sonra bir değer girin. Bu işlev, görünüm görünürlüğünü yüke göre değiştirmelidir
durum parametresi:
Kotlin
class LoadStateViewHolder( parent: ViewGroup, retry: () -> Unit ) : RecyclerView.ViewHolder( LayoutInflater.from(parent.context) .inflate(R.layout.load_state_item, parent, false) ) { private val binding = LoadStateItemBinding.bind(itemView) private val progressBar: ProgressBar = binding.progressBar private val errorMsg: TextView = binding.errorMsg private val retry: Button = binding.retryButton .also { it.setOnClickListener { retry() } } fun bind(loadState: LoadState) { if (loadState is LoadState.Error) { errorMsg.text = loadState.error.localizedMessage } progressBar.isVisible = loadState is LoadState.Loading retry.isVisible = loadState is LoadState.Error errorMsg.isVisible = loadState is LoadState.Error } }
Java
class LoadStateViewHolder extends RecyclerView.ViewHolder { private ProgressBar mProgressBar; private TextView mErrorMsg; private Button mRetry; LoadStateViewHolder( @NonNull ViewGroup parent, @NonNull View.OnClickListener retryCallback) { super(LayoutInflater.from(parent.getContext()) .inflate(R.layout.load_state_item, parent, false)); LoadStateItemBinding binding = LoadStateItemBinding.bind(itemView); mProgressBar = binding.progressBar; mErrorMsg = binding.errorMsg; mRetry = binding.retryButton; } public void bind(LoadState loadState) { if (loadState instanceof LoadState.Error) { LoadState.Error loadStateError = (LoadState.Error) loadState; mErrorMsg.setText(loadStateError.getError().getLocalizedMessage()); } mProgressBar.setVisibility(loadState instanceof LoadState.Loading ? View.VISIBLE : View.GONE); mRetry.setVisibility(loadState instanceof LoadState.Error ? View.VISIBLE : View.GONE); mErrorMsg.setVisibility(loadState instanceof LoadState.Error ? View.VISIBLE : View.GONE); } }
Java
class LoadStateViewHolder extends RecyclerView.ViewHolder { private ProgressBar mProgressBar; private TextView mErrorMsg; private Button mRetry; LoadStateViewHolder( @NonNull ViewGroup parent, @NonNull View.OnClickListener retryCallback) { super(LayoutInflater.from(parent.getContext()) .inflate(R.layout.load_state_item, parent, false)); LoadStateItemBinding binding = LoadStateItemBinding.bind(itemView); mProgressBar = binding.progressBar; mErrorMsg = binding.errorMsg; mRetry = binding.retryButton; } public void bind(LoadState loadState) { if (loadState instanceof LoadState.Error) { LoadState.Error loadStateError = (LoadState.Error) loadState; mErrorMsg.setText(loadStateError.getError().getLocalizedMessage()); } mProgressBar.setVisibility(loadState instanceof LoadState.Loading ? View.VISIBLE : View.GONE); mRetry.setVisibility(loadState instanceof LoadState.Error ? View.VISIBLE : View.GONE); mErrorMsg.setVisibility(loadState instanceof LoadState.Error ? View.VISIBLE : View.GONE); } }
Sonra, LoadStateAdapter uygulayan bir sınıf oluşturun ve
onCreateViewHolder()
ve
onBindViewHolder()
yöntemlerine göz atın. Bu yöntemler, özel görünüm sahibi ve bağlantınızın bir örneğini oluşturur
ilgili yükleme durumudur.
Kotlin
// Adapter that displays a loading spinner when // state is LoadState.Loading, and an error message and retry // button when state is LoadState.Error. class ExampleLoadStateAdapter( private val retry: () -> Unit ) : LoadStateAdapter<LoadStateViewHolder>() { override fun onCreateViewHolder( parent: ViewGroup, loadState: LoadState ) = LoadStateViewHolder(parent, retry) override fun onBindViewHolder( holder: LoadStateViewHolder, loadState: LoadState ) = holder.bind(loadState) }
Java
// Adapter that displays a loading spinner when // state is LoadState.Loading, and an error message and retry // button when state is LoadState.Error. class ExampleLoadStateAdapter extends LoadStateAdapter<LoadStateViewHolder> { private View.OnClickListener mRetryCallback; ExampleLoadStateAdapter(View.OnClickListener retryCallback) { mRetryCallback = retryCallback; } @NotNull @Override public LoadStateViewHolder onCreateViewHolder(@NotNull ViewGroup parent, @NotNull LoadState loadState) { return new LoadStateViewHolder(parent, mRetryCallback); } @Override public void onBindViewHolder(@NotNull LoadStateViewHolder holder, @NotNull LoadState loadState) { holder.bind(loadState); } }
Java
// Adapter that displays a loading spinner when // state is LoadState.Loading, and an error message and retry // button when state is LoadState.Error. class ExampleLoadStateAdapter extends LoadStateAdapter<LoadStateViewHolder> { private View.OnClickListener mRetryCallback; ExampleLoadStateAdapter(View.OnClickListener retryCallback) { mRetryCallback = retryCallback; } @NotNull @Override public LoadStateViewHolder onCreateViewHolder(@NotNull ViewGroup parent, @NotNull LoadState loadState) { return new LoadStateViewHolder(parent, mRetryCallback); } @Override public void onBindViewHolder(@NotNull LoadStateViewHolder holder, @NotNull LoadState loadState) { holder.bind(loadState); } }
Yükleme durumunu üstbilgi veya altbilgi olarak görüntüleme
Yükleme durumunu üstbilgi ve altbilgide görüntülemek için
withLoadStateHeaderAndFooter()
yöntemini PagingDataAdapter nesnenizden kaldırın:
Kotlin
pagingAdapter .withLoadStateHeaderAndFooter( header = ExampleLoadStateAdapter(adapter::retry), footer = ExampleLoadStateAdapter(adapter::retry) )
Java
pagingAdapter .withLoadStateHeaderAndFooter( new ExampleLoadStateAdapter(pagingAdapter::retry), new ExampleLoadStateAdapter(pagingAdapter::retry));
Java
pagingAdapter .withLoadStateHeaderAndFooter( new ExampleLoadStateAdapter(pagingAdapter::retry), new ExampleLoadStateAdapter(pagingAdapter::retry));
Bunun yerine şu numarayı arayabilirsiniz:
withLoadStateHeader()
veya
withLoadStateFooter()
RecyclerView listesinin yalnızca
veya yalnızca altbilgiye ekleyin.
Ek yükleme durumu bilgilerine erişme
PagingDataAdapter konumundaki CombinedLoadStates nesnesi şunun hakkında bilgi sağlar:
PagingSource uygulamanızın ve ayrıca
Varsa RemoteMediator uygulaması.
Kolaylık olması için
refresh
append ve
prepend
mülkünün bir LoadState nesnesine erişmek için CombinedLoadStates
uygun bir yükleme türü seçin. Bu özellikler genellikle
varsa RemoteMediator uygulaması; Aksi takdirde,
PagingSource uygulamasından uygun yükleme durumunu kontrol edin. Daha ayrıntılı
daha fazla bilgi edinmek için referans belgelerine bakın.
CombinedLoadStates.
Kotlin
lifecycleScope.launch { pagingAdapter.loadStateFlow.collectLatest { loadStates -> // Observe refresh load state from RemoteMediator if present, or // from PagingSource otherwise. refreshLoadState: LoadState = loadStates.refresh // Observe prepend load state from RemoteMediator if present, or // from PagingSource otherwise. prependLoadState: LoadState = loadStates.prepend // Observe append load state from RemoteMediator if present, or // from PagingSource otherwise. appendLoadState: LoadState = loadStates.append } }
Java
pagingAdapter.addLoadStateListener(loadStates -> { // Observe refresh load state from RemoteMediator if present, or // from PagingSource otherwise. LoadState refreshLoadState = loadStates.refresh; // Observe prepend load state from RemoteMediator if present, or // from PagingSource otherwise. LoadState prependLoadState = loadStates.prepend; // Observe append load state from RemoteMediator if present, or // from PagingSource otherwise. LoadState appendLoadState = loadStates.append; });
Java
pagingAdapter.addLoadStateListener(loadStates -> { // Observe refresh load state from RemoteMediator if present, or // from PagingSource otherwise. LoadState refreshLoadState = loadStates.refresh; // Observe prepend load state from RemoteMediator if present, or // from PagingSource otherwise. LoadState prependLoadState = loadStates.prepend; // Observe append load state from RemoteMediator if present, or // from PagingSource otherwise. LoadState appendLoadState = loadStates.append; });
Ancak, yalnızca PagingSource yükleme durumunun göz önünde bulundurulması önemlidir.
kullanıcı arayüzü güncellemeleriyle eşzamanlı olacağı garanti edilir. Çünkü refresh,
append ve prepend mülkleri, yükleme durumunu şuradan alabilir:
PagingSource veya RemoteMediator arasında geçiş yapılırsa
kullanıcı arayüzü güncellemeleriyle senkronize edilir. Bu durum, yüklemenin göründüğü yerlerde kullanıcı arayüzü sorunlarına neden olabilir
kullanıcı arayüzüne yeni veriler eklenmeden önce tamamlanması gerekir.
Bu nedenle, kolaylık sağlayan erişim araçları yükü iyi bir şekilde görüntüleyebilir.
bunu bir üstbilgide veya altbilgide eklersiniz, ancak diğer kullanım alanları için
yükleme durumuna özellikle PagingSource veya
RemoteMediator. CombinedLoadStates,
source ve
mediator
bu özellikleri kullanabilirsiniz. Bu özelliklerin her biri,
LoadStates nesne
PagingSource veya RemoteMediator için LoadState nesnelerini içerir
oluşturmak için:
Kotlin
lifecycleScope.launch { pagingAdapter.loadStateFlow.collectLatest { loadStates -> // Directly access the RemoteMediator refresh load state. mediatorRefreshLoadState: LoadState? = loadStates.mediator.refresh // Directly access the RemoteMediator append load state. mediatorAppendLoadState: LoadState? = loadStates.mediator.append // Directly access the RemoteMediator prepend load state. mediatorPrependLoadState: LoadState? = loadStates.mediator.prepend // Directly access the PagingSource refresh load state. sourceRefreshLoadState: LoadState = loadStates.source.refresh // Directly access the PagingSource append load state. sourceAppendLoadState: LoadState = loadStates.source.append // Directly access the PagingSource prepend load state. sourcePrependLoadState: LoadState = loadStates.source.prepend } }
Java
pagingAdapter.addLoadStateListener(loadStates -> { // Directly access the RemoteMediator refresh load state. LoadState mediatorRefreshLoadState = loadStates.mediator.refresh; // Directly access the RemoteMediator append load state. LoadState mediatorAppendLoadState = loadStates.mediator.append; // Directly access the RemoteMediator prepend load state. LoadState mediatorPrependLoadState = loadStates.mediator.prepend; // Directly access the PagingSource refresh load state. LoadState sourceRefreshLoadState = loadStates.source.refresh; // Directly access the PagingSource append load state. LoadState sourceAppendLoadState = loadStates.source.append; // Directly access the PagingSource prepend load state. LoadState sourcePrependLoadState = loadStates.source.prepend; });
Java
pagingAdapter.addLoadStateListener(loadStates -> { // Directly access the RemoteMediator refresh load state. LoadState mediatorRefreshLoadState = loadStates.mediator.refresh; // Directly access the RemoteMediator append load state. LoadState mediatorAppendLoadState = loadStates.mediator.append; // Directly access the RemoteMediator prepend load state. LoadState mediatorPrependLoadState = loadStates.mediator.prepend; // Directly access the PagingSource refresh load state. LoadState sourceRefreshLoadState = loadStates.source.refresh; // Directly access the PagingSource append load state. LoadState sourceAppendLoadState = loadStates.source.append; // Directly access the PagingSource prepend load state. LoadState sourcePrependLoadState = loadStates.source.prepend; });
LoadState'te zincir operatörleri
Çünkü CombinedLoadStates nesnesi,
yükleme durumuna göre, yükleme durumu akışını belirli ölçütlere göre
etkinlikler. Bu sayede kullanıcı arayüzünüzü, uygulama yükleme işleminden kaçınmak için uygun zamanda güncellemeniz gerekir.
takılmalar ve gereksiz kullanıcı arayüzü güncellemeleri.
Örneğin, boş bir görünüm görüntülemek istediğinizi, ancak yalnızca
yüklemenin tamamlanmasına
yardımcı olur. Bu kullanım alanı, bir veri türünün
yenileme yüklemesi başladı, ardından NotLoading durumunun onaylamasını bekleyin
yenileme tamamlandı. Şunlar dışındaki tüm sinyalleri filtrelemeniz gerekir:
ihtiyacınız olanlar:
Kotlin
lifecycleScope.launchWhenCreated { adapter.loadStateFlow // Only emit when REFRESH LoadState for RemoteMediator changes. .distinctUntilChangedBy { it.refresh } // Only react to cases where REFRESH completes, such as NotLoading. .filter { it.refresh is LoadState.NotLoading } // Scroll to top is synchronous with UI updates, even if remote load was // triggered. .collect { binding.list.scrollToPosition(0) } }
Java
PublishSubject<CombinedLoadStates> subject = PublishSubject.create(); Disposable disposable = subject.distinctUntilChanged(CombinedLoadStates::getRefresh) .filter( combinedLoadStates -> combinedLoadStates.getRefresh() instanceof LoadState.NotLoading) .subscribe(combinedLoadStates -> binding.list.scrollToPosition(0)); pagingAdapter.addLoadStateListener(loadStates -> { subject.onNext(loadStates); });
Java
LiveData<CombinedLoadStates> liveData = new MutableLiveData<>(); LiveData<LoadState> refreshLiveData = Transformations.map(liveData, CombinedLoadStates::getRefresh); LiveData<LoadState> distinctLiveData = Transformations.distinctUntilChanged(refreshLiveData); distinctLiveData.observeForever(loadState -> { if (loadState instanceof LoadState.NotLoading) { binding.list.scrollToPosition(0); } });
Bu örnek, yenileme yükleme durumu güncellenene kadar bekler, ancak yalnızca şu tetikleyicileri tetikler:
eyalet NotLoading olduğunda. Bu şekilde, uzaktan yenileme işleminin
kullanıcı arayüzü güncellemesi
yapılmadan biter.
Akış API'leri bu tür işlemleri mümkün kılar. Uygulamanız yükü belirtebilir ve uygun ölçütler karşılandığında yeni verileri işler.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Sayfalandırılmış verileri yükleme ve görüntüleme
- Ağ ve veritabanındaki sayfa
- Çağrı kitaplığına genel bakış