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
LoadState
birLoadState.NotLoading
nesnesini 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.Loading
nesnesini tanımlayın. - Hata varsa
LoadState
,LoadState.Error
nesnesini 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ış