पेजिंग लाइब्रेरी, बड़े डेटासेट से पेज किया गया डेटा लोड करने और दिखाने के लिए बेहतरीन सुविधाएं उपलब्ध कराती है. इस गाइड में, नेटवर्क डेटा सोर्स से पेज किए गए डेटा की स्ट्रीम सेट अप करने और उसे लेज़ी लिस्ट में दिखाने के लिए, Paging लाइब्रेरी का इस्तेमाल करने का तरीका बताया गया है.
डेटा सोर्स तय करना
डेटा सोर्स की पहचान करने के लिए, सबसे पहले PagingSource लागू करें. PagingSource API क्लास में load तरीका शामिल होता है. इसे ओवरराइड करके यह बताया जाता है कि संबंधित डेटा सोर्स से पेज किया गया डेटा कैसे वापस पाया जाए.
एसिंक लोडिंग के लिए Kotlin कोरूटीन का इस्तेमाल करने के लिए, सीधे तौर पर PagingSource क्लास का इस्तेमाल करें.
कुंजी और वैल्यू के टाइप चुनना
PagingSource<Key, Value> में दो टाइप पैरामीटर होते हैं: Key और Value. कुंजी, डेटा को लोड करने के लिए इस्तेमाल किए गए आइडेंटिफ़ायर के बारे में बताती है. वहीं, वैल्यू, डेटा के टाइप के बारे में बताती है. उदाहरण के लिए, अगर आपको नेटवर्क से User ऑब्जेक्ट के पेज लोड करने हैं, तो Retrofit को Int पेज नंबर पास करें. इसके लिए, Key टाइप के तौर पर Int और Value टाइप के तौर पर User चुनें.
PagingSource को तय करना
यहां दिए गए उदाहरण में, PagingSource को लागू करने का तरीका बताया गया है. यह पेज नंबर के हिसाब से आइटम के पेजों को लोड करता है. Key टाइप Int है और Value टाइप User है.
class ExamplePagingSource(
val backend: ExampleBackendService,
val query: String
) : PagingSource<Int, User>() {
override suspend fun load(
params: LoadParams<Int>
): LoadResult<Int, User> {
init {
// the data source is expected to be immutable
// invalidate PagingSource if data source
// has updated
backEnd.addDatabaseOnChangedListener {
invalidate()
}
}
try {
// Start refresh at page 1 if undefined.
val nextPageNumber = params.key ?: 1
val response = backend.searchUsers(query, nextPageNumber)
return LoadResult.Page(
data = response.users,
prevKey = null, // Only paging forward.
nextKey = nextPageNumber + 1
)
} catch (e: Exception) {
// Handle errors in this block and return LoadResult.Error for
// expected errors (such as a network failure).
}
}
override fun getRefreshKey(state: PagingState<Int, User>): Int? {
// Try to find the page key of the closest page to anchorPosition from
// either the prevKey or the nextKey; you need to handle nullability
// here.
// * prevKey == null -> anchorPage is the first page.
// * nextKey == null -> anchorPage is the last page.
// * both prevKey and nextKey are null -> anchorPage is the
// initial page, so return null.
return state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
}
}
}
PagingSource को लागू करने का सामान्य तरीका यह है कि इसके कंस्ट्रक्टर में दिए गए पैरामीटर को load तरीके से पास किया जाता है, ताकि क्वेरी के लिए सही डेटा लोड किया जा सके. ऊपर दिए गए उदाहरण में, ये पैरामीटर हैं:
backend: बैकएंड सेवा का एक ऐसा इंस्टेंस जो डेटा उपलब्ध कराता हैquery:backendमें बताई गई सेवा को भेजी जाने वाली खोज क्वेरी
LoadParams ऑब्जेक्ट में, लोड करने की कार्रवाई के बारे में जानकारी होती है. इसमें लोड की जाने वाली कुंजी और लोड किए जाने वाले आइटम की संख्या शामिल होती है.
LoadResult ऑब्जेक्ट में, लोड करने की कार्रवाई का नतीजा होता है. LoadResult एक सील की गई क्लास है. यह तीन में से किसी एक फ़ॉर्म में होती है. यह इस बात पर निर्भर करता है कि load कॉल पूरा हुआ या नहीं:
- अगर लोड हो जाता है, तो
LoadResult.Pageऑब्जेक्ट दिखाएं. - अगर लोड नहीं होता है, तो
LoadResult.Errorऑब्जेक्ट वापस भेजें. - अगर
PagingSourceअब मान्य नहीं है और इसे नए इंस्टेंस से बदला जाना चाहिए (उदाहरण के लिए, डेटा में बदलाव होने की वजह से), तोLoadResult.Invalidऑब्जेक्ट दिखाएं.
यहां दिए गए डायग्राम में दिखाया गया है कि इस उदाहरण में load फ़ंक्शन, हर लोड के लिए कुंजी कैसे पाता है और बाद के लोड के लिए कुंजी कैसे उपलब्ध कराता है.
load, कुंजी का इस्तेमाल कैसे करता है और उसे अपडेट कैसे करता है.
PagingSource को getRefreshKey तरीके को भी लागू करना होगा. यह तरीका, PagingState ऑब्जेक्ट को पैरामीटर के तौर पर लेता है. यह कुंजी, load तरीके में पास करने के लिए देता है. ऐसा तब होता है, जब शुरुआती लोड के बाद डेटा रीफ़्रेश हो जाता है या अमान्य हो जाता है. Paging लाइब्रेरी, डेटा के बाद के रीफ़्रेश पर इस तरीके को अपने-आप कॉल करती है.
गड़बड़ियां ठीक करना
डेटा लोड करने के अनुरोध कई वजहों से पूरे नहीं हो पाते. ऐसा खास तौर पर तब होता है, जब डेटा को नेटवर्क पर लोड किया जा रहा हो. load तरीके से LoadResult.Error ऑब्जेक्ट को वापस भेजकर, रिपोर्ट लोड करते समय हुई गड़बड़ियों की जानकारी दें.
उदाहरण के लिए, पिछले उदाहरण में मौजूद ExamplePagingSource में लोड होने से जुड़ी गड़बड़ियों का पता लगाया जा सकता है और उनकी शिकायत की जा सकती है. इसके लिए, load तरीके में यह कोड जोड़ें:
catch (e: IOException) {
// IOException for network failures.
return LoadResult.Error(e)
} catch (e: HttpException) {
// HttpException for any non-2xx HTTP status codes.
return LoadResult.Error(e)
}
Retrofit की गड़बड़ियों को ठीक करने के बारे में ज़्यादा जानने के लिए, PagingSource एपीआई रेफ़रंस में दिए गए सैंपल देखें.
PagingSource, LoadResult.Error ऑब्जेक्ट इकट्ठा करता है और उन्हें यूज़र इंटरफ़ेस (यूआई) पर दिखाता है, ताकि आप उन पर कार्रवाई कर सकें. यूज़र इंटरफ़ेस (यूआई) में लोडिंग की स्थिति दिखाने के बारे में ज़्यादा जानकारी के लिए, लोडिंग की स्थितियों को मैनेज करना और दिखाना लेख पढ़ें.
PagingData की स्ट्रीम सेट अप करना
इसके बाद, आपको PagingSource लागू करने से पेज किए गए डेटा की स्ट्रीम की ज़रूरत होगी.
अपने ViewModel में डेटा स्ट्रीम सेट अप करें. Pager क्लास, ऐसे तरीके उपलब्ध कराती है जो PagingSource से PagingData ऑब्जेक्ट की रिएक्टिव स्ट्रीम को दिखाते हैं. Paging लाइब्रेरी, डेटा की स्ट्रीम को Flow के तौर पर दिखाती है.
जब आपको अपनी रिएक्टिव स्ट्रीम सेट अप करने के लिए, Pager इंस्टेंस बनाना हो, तो आपको इंस्टेंस को PagingConfig कॉन्फ़िगरेशन ऑब्जेक्ट और एक ऐसा फ़ंक्शन देना होगा जो Pager को बताए कि PagingSource के इंस्टेंस को कैसे पाना है. इसका उदाहरण यहां दिया गया है.
class UserViewModel(
private val backend: ExampleBackendService,
private val query: String
) : ViewModel() {
val userPagingFlow: Flow<PagingData<User>> = Pager(
// Configure how data is loaded by passing additional properties to
// PagingConfig, such as pageSize and enabling or disabling placeholders.
config = PagingConfig(
pageSize = 20,
enablePlaceholders = true
),
pagingSourceFactory = {
ExamplePagingSource(backend, query)
}
)
.flow
.cachedIn(viewModelScope)
}
cachedIn ऑपरेटर, डेटा स्ट्रीम को शेयर करने की सुविधा देता है. साथ ही, लोड किए गए डेटा को दिए गए CoroutineScope के साथ कैश मेमोरी में सेव करता है. cachedIn के बिना, PagingData को फिर से इकट्ठा नहीं किया जा सकता. इस उदाहरण में, लाइफ़साइकल lifecycle-viewmodel-ktx आर्टफ़ैक्ट से मिले viewModelScope का इस्तेमाल किया गया है.
Pager ऑब्जेक्ट, PagingSource ऑब्जेक्ट से load तरीके को कॉल करता है. साथ ही, इसे LoadParams ऑब्जेक्ट उपलब्ध कराता है और बदले में LoadResult ऑब्जेक्ट पाता है.
अपने यूज़र इंटरफ़ेस (यूआई) में डेटा इकट्ठा करना और उसे दिखाना
पेज वाली स्ट्रीम को यूज़र इंटरफ़ेस (यूआई) से कनेक्ट करने के लिए, अपने ViewModel से फ़्लो पाएं और इसे अपनी सूची में शामिल करने लायक आइटम को पास करें.
@Composable
fun UserScreen(viewModel: UserViewModel = viewModel()) {
val userFlow = viewModel.userPagingFlow
UserList(flow = userFlow)
}
PagingData फ़्लो को LazyPagingItems में बदलने के लिए, collectAsLazyPagingItems का इस्तेमाल करें. इसके बाद, हर आइटम को लेआउट करने के लिए, items के अंदर items एपीआई का इस्तेमाल करें.LazyColumn
पक्का करें कि आपने itemKey का इस्तेमाल करके, हर आइटम के लिए एक यूनीक और स्टेबल आइडेंटिफ़ायर दिया हो.
यहां दिए गए उदाहरण में, it.id (User.id प्रॉपर्टी को रेफ़रंस करना) का इस्तेमाल किया गया है. ऐसा इसलिए, क्योंकि डेटा अपडेट होने पर भी User इंस्टेंस के लिए यह स्थिर रहता है.
@Composable
fun UserList(flow: Flow<PagingData<User>>) {
val lazyPagingItems = flow.collectAsLazyPagingItems()
LazyColumn {
items(
lazyPagingItems.itemCount,
key = lazyPagingItems.itemKey { it.id }
) { index ->
val user = lazyPagingItems[index]
if (user != null) {
UserRow(user)
} else {
UserPlaceholder()
}
}
}
}
पेज लोड होने के दौरान, Paging लाइब्रेरी प्लेसहोल्डर के लिए null का इस्तेमाल करती है. इसलिए, अगर आपने प्लेसहोल्डर चालू किए हैं, तो आपको कॉन्टेंट ब्लॉक में null वैल्यू मैनेज करनी होंगी.
अब सूची में पेज वाला डेटा दिखता है. साथ ही, उपयोगकर्ता के स्क्रोल करने पर, पेजिंग लाइब्रेरी अतिरिक्त पेज लोड करती है.
अन्य संसाधन
पेजिंग लाइब्रेरी के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें:
दस्तावेज़
कॉन्टेंट देखता है
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक का टेक्स्ट दिखता है
- नेटवर्क और डेटाबेस से पेज
- Paging 3 पर माइग्रेट करना
- Paging library के बारे में खास जानकारी