Site icon C1CTech

Android Paging 3 Example Using Retrofit

&NewLine;<p>This post is about Android Jetpack Paging 3 library and how we can use it to load the large set of data from network using Retrofit in our RecyclerView efficiently with the help of <strong>AndroidPagingExp<&sol;strong> application&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<div class&equals;"wp-block-buttons is-content-justification-center is-layout-flex wp-block-buttons-is-layout-flex"> &NewLine;<div class&equals;"wp-block-button"><a class&equals;"wp-block-button&lowbar;&lowbar;link has-white-color has-text-color has-background" style&equals;"background-color&colon; &num;14066f&semi;" href&equals;"https&colon;&sol;&sol;github&period;com&sol;arunk7839&sol;JetpackPaging3ExpUsingRetrofit" target&equals;"&lowbar;blank" rel&equals;"noreferrer noopener"><strong>DOWNLOAD CODE<&sol;strong><&sol;a><&sol;div> &NewLine;<&sol;div> &NewLine; &NewLine; &NewLine; &NewLine;<h4 class&equals;"wp-block-heading"> <&sol;h4> &NewLine;<p><amp-youtube layout&equals;"responsive" width&equals;"1200" height&equals;"675" data-videoid&equals;"h68dN7JsMd4" title&equals;"Android Paging 3 Example Using Retrofit"><a placeholder href&equals;"https&colon;&sol;&sol;youtu&period;be&sol;h68dN7JsMd4"><img src&equals;"https&colon;&sol;&sol;i&period;ytimg&period;com&sol;vi&sol;h68dN7JsMd4&sol;hqdefault&period;jpg" layout&equals;"fill" object-fit&equals;"cover" alt&equals;"Android Paging 3 Example Using Retrofit"><&sol;a><&sol;amp-youtube><&sol;p> &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>Android Paging <&sol;strong><&sol;span><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>The <strong><span style&equals;"color&colon; &num;008000&semi;">Paging<&sol;span><&sol;strong> library helps you load and display pages of data or small chunks of data at a time from a larger dataset from local storage or over network&period; Loading partial data on demand reduces usage of network bandwidth and system resources&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<p> It integrates cleanly with other Jetpack components&comma; and provide first-class Kotlin support&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<h4 class&equals;"wp-block-heading" id&equals;"paging"><strong><span class&equals;"devsite-heading" style&equals;"color&colon; &num;000080&semi;" role&equals;"heading" aria-level&equals;"2">Benefits of using the Paging library<&sol;span><&sol;strong><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>The Paging library includes the following features&colon;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<ul class&equals;"wp-block-list"> &NewLine;<li>Provides in-memory caching of the paged data that assures the systematic use of device resources&period;<&sol;li> &NewLine;<li>Prevents duplication of the API request&comma; ensuring that your app uses network bandwidth and system resources efficiently&period;<&sol;li> &NewLine;<li>Configurable RecyclerView adapters that automatically request data as the user scrolls toward the end of the loaded data&period;<&sol;li> &NewLine;<li>Finest support for Kotlin coroutines and Flow&comma; as well as LiveData and RxJava&period;<&sol;li> &NewLine;<li>Built-in functionality to add loading state headers&comma; footers&comma; and list separators&period;<&sol;li> &NewLine;<li>Built-in support for error handling&comma; including refresh and retry capabilities&period;<&sol;li> &NewLine;<&sol;ul> &NewLine; &NewLine; &NewLine; &NewLine;<h4 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong>Paging Library Components<&sol;strong><&sol;span><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p> To implement &OpenCurlyDoubleQuote;infinite scroll” functionality &comma; we will use the following Paging library components&colon;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<ul class&equals;"wp-block-list"> &NewLine;<li id&equals;"7a75" class&equals;"hq hr dm hs b ht hu hv hw hx hy hz ia ib ic id ie if ig ih ii ij ik il im in lf lg lh ej" data-selectable-paragraph&equals;""><span style&equals;"color&colon; &num;0000ff&semi;"><strong class&equals;"hs io">PagingData<&sol;strong><&sol;span> &colon;  A container for paginated data&period; It connects the <span style&equals;"color&colon; &num;008000&semi;"><strong>ViewModel<&sol;strong><&sol;span> layer to the <span style&equals;"color&colon; &num;008000&semi;"><strong>UI<&sol;strong><&sol;span>&period; <&sol;li> &NewLine;<li id&equals;"6ec3" class&equals;"hq hr dm hs b ht lm hv hw hx ln hz ia ib lo id ie if lp ih ii ij lq il im in lf lg lh ej" data-selectable-paragraph&equals;""><span style&equals;"color&colon; &num;0000ff&semi;"><strong class&equals;"hs io">PagingSource<&sol;strong><&sol;span> &colon; PagingSource object defines a source of data and how to retrieve data from that source&period; A PagingSource object can load data from any single source&comma; including network sources and local databases&period;<&sol;li> &NewLine;<li class&equals;"hq hr dm hs b ht lm hv hw hx ln hz ia ib lo id ie if lp ih ii ij lq il im in lf lg lh ej" data-selectable-paragraph&equals;""><strong class&equals;"hs io"><span style&equals;"color&colon; &num;0000ff&semi;">Pager&period;flow<&sol;span> <&sol;strong>&colon; builds a <span style&equals;"color&colon; &num;008000&semi;"><strong>Flow&lt&semi;PagingData&gt&semi;<&sol;strong><&sol;span>&period;<&sol;li> &NewLine;<li class&equals;"hq hr dm hs b ht lm hv hw hx ln hz ia ib lo id ie if lp ih ii ij lq il im in lf lg lh ej" data-selectable-paragraph&equals;""><span style&equals;"color&colon; &num;0000ff&semi;"><strong class&equals;"hs io">PagingDataAdapter<&sol;strong><&sol;span> &colon; a <span style&equals;"color&colon; &num;008000&semi;"><strong>RecyclerView&period;Adapter<&sol;strong> <&sol;span>that presents <span style&equals;"color&colon; &num;008000&semi;"><strong>PagingData<&sol;strong><&sol;span> in a <strong><span style&equals;"color&colon; &num;008000&semi;">RecyclerView<&sol;span><&sol;strong>&period; <&sol;li> &NewLine;<&sol;ul> &NewLine; &NewLine; &NewLine; &NewLine;<div class&equals;"wp-block-image"> &NewLine;<figure class&equals;"aligncenter"><img class&equals;"wp-image-2894 aligncenter" src&equals;"https&colon;&sol;&sol;c1ctech&period;com&sol;wp-content&sol;uploads&sol;2021&sol;10&sol;paging&period;png" alt&equals;"" &sol;><&sol;figure> &NewLine;<&sol;div> &NewLine; &NewLine; &NewLine; &NewLine;<h4 class&equals;"wp-block-heading"> <&sol;h4> &NewLine;<h4><strong><span style&equals;"color&colon; &num;000080&semi;">Creating new Project<&sol;span><&sol;strong><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>1 &period; Create a new project by going to <strong><span style&equals;"color&colon; &num;008000&semi;">File &Implies; New<&sol;span> <&sol;strong>Android Project&comma; select <span style&equals;"color&colon; &num;008000&semi;"><strong>Empty<&sol;strong><&sol;span> Activity&comma; provide <span style&equals;"color&colon; &num;008000&semi;"><strong>app<&sol;strong><&sol;span> name&comma; select language to <span style&equals;"color&colon; &num;008000&semi;"><strong>kotlin<&sol;strong><&sol;span> and then finally click on <strong><span style&equals;"color&colon; &num;008000&semi;">finish<&sol;span><&sol;strong>&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine; &NewLine; &NewLine;<p>2 &period; Open app-level <span style&equals;"color&colon; &num;008000&semi;"><strong>build&period;gradle<&sol;strong><&sol;span> file&comma; add the below dependencies as shown below&comma; and then <strong><span style&equals;"color&colon; &num;0000ff&semi;">sync<&sol;span><&sol;strong> the project&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>build&period;gradle<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">dependencies &lbrace; &NewLine;<strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; Android Jetpack Paging 3&period;0 &NewLine;<&sol;span><&sol;strong> implementation "androidx&period;paging&colon;paging-runtime&colon;3&period;0&period;0-alpha06" &NewLine; &NewLine;<strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; ViewModel &NewLine;<&sol;span><&sol;strong> implementation "androidx&period;lifecycle&colon;lifecycle-viewmodel-ktx&colon;2&period;2&period;0" &NewLine; &NewLine;<span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol; Retrofit &NewLine;<&sol;strong><&sol;span> implementation 'com&period;squareup&period;retrofit2&colon;retrofit&colon;2&period;9&period;0' &NewLine; implementation 'com&period;squareup&period;retrofit2&colon;converter-gson&colon;2&period;4&period;0' <span style&equals;"color&colon; &num;008000&semi;"><strong>&sol;&sol; Gson support adapter for Retrofit<&sol;strong><&sol;span> &NewLine; implementation "com&period;squareup&period;okhttp3&colon;logging-interceptor&colon;4&period;9&period;0" <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol;OKHttp Interceptor &NewLine;<&sol;span><&sol;strong> &NewLine;<strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;Kotlin Coroutines &NewLine;<&sol;span><&sol;strong> implementation "org&period;jetbrains&period;kotlinx&colon;kotlinx-coroutines-android&colon;1&period;3&period;9" &NewLine; implementation "org&period;jetbrains&period;kotlinx&colon;kotlinx-coroutines-core&colon;1&period;3&period;9" &NewLine; &NewLine;<strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;Glide to load images from URL &NewLine;<&sol;span><&sol;strong> implementation 'com&period;github&period;bumptech&period;glide&colon;glide&colon;4&period;11&period;0' &NewLine; implementation 'androidx&period;databinding&colon;databinding-runtime&colon;7&period;0&period;3' &NewLine; annotationProcessor 'com&period;github&period;bumptech&period;glide&colon;compiler&colon;4&period;11&period;0' &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p>3&period; Inside <strong><span style&equals;"color&colon; &num;008000&semi;">android&lbrace;&rcub;<&sol;span> <&sol;strong>block enable <strong><span style&equals;"color&colon; &num;008000&semi;">viewBinding<&sol;span><&sol;strong>&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">viewBinding &lbrace; &NewLine; <strong><span style&equals;"color&colon; &num;008000&semi;"> enabled true<&sol;span><&sol;strong> &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p>4&period; Go to <span style&equals;"color&colon; &num;008000&semi;"><strong>AndroidManifest&period;xml<&sol;strong><&sol;span> and add the internet permission above <span style&equals;"color&colon; &num;008000&semi;"><strong>&lt&semi;application&gt&semi;<&sol;strong><&sol;span> tag as shown below&colon;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>AndroidManifest&period;xml<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">&lt&semi;uses-permission android&colon;name&equals;"android&period;permission&period;INTERNET" &sol;&gt&semi;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine; &NewLine; &NewLine;<h4 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong>Setting Up Retrofit<&sol;strong><&sol;span><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>Now let’s setup our Retrofit that will hit the backend API to fetch data sets&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<h5 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong>Backend API<&sol;strong><&sol;span><&sol;h5> &NewLine; &NewLine; &NewLine; &NewLine;<p>In our project&comma; we will use the below free JSON API&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">https&colon;&sol;&sol;api&period;instantwebtools&period;net&sol;v1&sol;passenger&quest;page&equals;0&amp&semi;size&equals;10<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<h5 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating API Interface<&sol;strong><&sol;span><&sol;h5> &NewLine; &NewLine; &NewLine; &NewLine;<p>Create an interface named <span style&equals;"color&colon; &num;008000&semi;"><strong>MyApi<&sol;strong><&sol;span> and write the following code&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>MyApi&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">interface MyApi &lbrace; &NewLine; &NewLine; &commat;GET&lpar;"passenger"&rpar; &NewLine; suspend fun getPassengersData&lpar; &NewLine; &commat;Query&lpar;"page"&rpar; page&colon; Int&comma; &NewLine; &commat;Query&lpar;"size"&rpar; size&colon; Int &equals; 10 &NewLine; &rpar;&colon; PassengersResponse &NewLine; &NewLine; companion object &lbrace; &NewLine; &NewLine; private const val BASE&lowbar;URL &equals; "https&colon;&sol;&sol;api&period;instantwebtools&period;net&sol;v1&sol;" &NewLine; &NewLine; operator fun invoke&lpar;&rpar;&colon; MyApi &equals; Retrofit&period;Builder&lpar;&rpar; &NewLine; &period;baseUrl&lpar;BASE&lowbar;URL&rpar; &NewLine; &period;addConverterFactory&lpar;GsonConverterFactory&period;create&lpar;&rpar;&rpar; &NewLine; &period;build&lpar;&rpar; &NewLine; &period;create&lpar;MyApi&colon;&colon;class&period;java&rpar; &NewLine; &rcub; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine; &NewLine; &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">getPassangersData&lpar;&rpar;<&sol;span><&sol;strong> &colon; A function which will hit a <span style&equals;"color&colon; &num;008000&semi;"><strong>GET<&sol;strong><&sol;span> request using the query parameter <strong>page<&sol;strong> and <strong>size<&sol;strong>&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>companion object&lbrace; &rcub; <&sol;strong><&sol;span>&colon; Inside this&comma; we have the base URL and the invoke function that will return us the <strong>MyApi<&sol;strong> Instance&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<h5 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong><span id&equals;"Data-Classes-to-Map-API-Response">Data Classes to Map API Response<&sol;span><&sol;strong><&sol;span><&sol;h5> &NewLine; &NewLine; &NewLine; &NewLine;<p>Now&comma; we have to create the data class for the following JSON output which we get as the response&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">&lbrace; &NewLine; "totalPassengers"&colon; 19851&comma; &NewLine; "totalPages"&colon; 19851&comma; &NewLine; "data"&colon; &lbrack; &NewLine; &lbrace; &NewLine; "&lowbar;id"&colon; "5fec58acc9a1dc9a93bca8c2"&comma; &NewLine; "name"&colon; "John Doe"&comma; &NewLine; "trips"&colon; 500&comma; &NewLine; "airline"&colon; &lbrack; &NewLine; &lbrace; &NewLine; "id"&colon; 8&comma; &NewLine; "name"&colon; "Thai Airways"&comma; &NewLine; "country"&colon; "Thailand"&comma; &NewLine; "logo"&colon; "https&colon;&sol;&sol;upload&period;wikimedia&period;org&sol;wikipedia&sol;en&sol;thumb&sol;5&sol;58&sol;Thai&lowbar;Airways&lowbar;Logo&period;svg&sol;200px-Thai&lowbar;Airways&lowbar;Logo&period;svg&period;png"&comma; &NewLine; "slogan"&colon; "Smooth as Silk &sol; I Fly THAI"&comma; &NewLine; "head&lowbar;quaters"&colon; "Jom Phol Subdistrict&comma; Chatuchak&comma; Bangkok&comma; Thailand"&comma; &NewLine; "website"&colon; "www&period;thaiairways&period;com"&comma; &NewLine; "established"&colon; "1960" &NewLine; &rcub; &NewLine; &rsqb;&comma; &NewLine; "&lowbar;&lowbar;v"&colon; 0 &NewLine; &rcub; &NewLine; &rsqb; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p>Given below are the corresponding data classes for the above JSON response&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<ul> &NewLine;<li>The <span style&equals;"color&colon; &num;008000&semi;"><strong>PassengersResponse<&sol;strong><&sol;span> data class looks like&comma;<&sol;li> &NewLine;<&sol;ul> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>PassengersResponse&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">data class PassengersResponse&lpar; &NewLine; val &grave;data&grave;&colon; List&lt&semi;Passenger&gt&semi;&comma; &NewLine; val totalPages&colon; Int&comma; &NewLine; val totalPassengers&colon; In &NewLine;&rpar;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<ul> &NewLine;<li>The <span style&equals;"color&colon; &num;008000&semi;"><strong>Passenger<&sol;strong><&sol;span> data class looks like&comma;<&sol;li> &NewLine;<&sol;ul> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>Passenger&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">data class Passenger&lpar; &NewLine; val &lowbar;&lowbar;v&colon; Int&comma; &NewLine; val &lowbar;id&colon; String&comma; &NewLine; val airline&colon; List&lt&semi;Airline&gt&semi;&comma; &NewLine; val name&colon; String&comma; &NewLine; val trips&colon; Int &NewLine;&rpar;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<ul> &NewLine;<li>The <span style&equals;"color&colon; &num;008000&semi;"><strong>Airline<&sol;strong><&sol;span> data class looks like&comma;<&sol;li> &NewLine;<&sol;ul> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>Airline&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">data class Airline&lpar; &NewLine; val country&colon; String&comma; &NewLine; val established&colon; String&comma; &NewLine; val head&lowbar;quaters&colon; String&comma; &NewLine; val id&colon; Int&comma; &NewLine; val logo&colon; String&comma; &NewLine; val name&colon; String&comma; &NewLine; val slogan&colon; String&comma; &NewLine; val website&colon; String &NewLine;&rpar;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine; &NewLine; &NewLine;<h4 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong class&equals;"id iz">PagingSource<&sol;strong><&sol;span><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>A <strong><span style&equals;"color&colon; &num;008000&semi;">PagingSource<&sol;span><&sol;strong> class is used to access data from the backend API&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<p>The <strong><span style&equals;"color&colon; &num;008000&semi;">PassengersDataSource<&sol;span><&sol;strong> class extends PagingSource class and takes a primary constructor parameter <span style&equals;"color&colon; &num;008000&semi;"><strong>MyApi<&sol;strong><&sol;span>&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">PassengersDataSource&period;kt<&sol;span><&sol;strong><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">class PassengersDataSource&lpar;private val api&colon; MyApi&rpar; &colon; PagingSource&lt&semi;Int&comma; Passenger&gt&semi;&lpar;&rpar; &lbrace; &NewLine; &NewLine; override suspend fun load&lpar;params&colon; LoadParams&lt&semi;Int&gt&semi;&rpar;&colon; LoadResult&lt&semi;Int&comma; Passenger&gt&semi; &lbrace;&rcub; &NewLine; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<ul class&equals;"wp-block-list"> &NewLine;<li>PagingSource takes two parameters&comma; a key and a value&period; &NewLine;<ul> &NewLine;<li><strong><span style&equals;"color&colon; &num;0000ff&semi;">key<&sol;span><&sol;strong>&colon; what data to load&period; E&period;g&period; <span style&equals;"color&colon; &num;008000&semi;"><strong>Int<&sol;strong><&sol;span> as a page number or <span style&equals;"color&colon; &num;008000&semi;"><strong>String<&sol;strong><&sol;span> as a next page token&period;<&sol;li> &NewLine;<li><strong><span style&equals;"color&colon; &num;0000ff&semi;">value<&sol;span><&sol;strong>&colon; type of data<span style&equals;"color&colon; &num;008000&semi;"><strong> &lpar;Passenger&rpar;<&sol;strong><&sol;span> that will be loaded&period;<&sol;li> &NewLine;<&sol;ul> &NewLine;<&sol;li> &NewLine;<li>The <span style&equals;"color&colon; &num;0000ff&semi;"><strong>load&lpar;&rpar;<&sol;strong><&sol;span> function returns a <span style&equals;"color&colon; &num;008000&semi;"><strong>LoadResult<&sol;strong><&sol;span> and should be implemented to retrieve data from the data source &lpar;network in our case&rpar;&period;<&sol;li> &NewLine;<li><span style&equals;"color&colon; &num;000000&semi;">load&lpar;&rpar;<&sol;span> is a <strong><span style&equals;"color&colon; &num;0000ff&semi;">suspend<&sol;span><&sol;strong> function&comma; so you can call other suspend functions here&comma; such as the network call&period;<&sol;li> &NewLine;<&sol;ul> &NewLine; &NewLine; &NewLine; &NewLine;<p>Now&comma; we update the load function like&colon;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted"> override suspend fun load&lpar;params&colon; LoadParams&lt&semi;Int&gt&semi;&rpar;&colon; LoadResult&lt&semi;Int&comma; Passenger&gt&semi; &lbrace; &NewLine; return try &lbrace; &NewLine; val nextPageNumber &equals; params&period;key &quest;&colon; 0 &NewLine; val response &equals; api&period;getPassengersData&lpar;nextPageNumber&rpar; &NewLine; &NewLine; LoadResult&period;Page&lpar; &NewLine; data &equals; response&period;data&comma; &NewLine; prevKey &equals; if &lpar;nextPageNumber &gt&semi; 0&rpar; nextPageNumber - 1 else null&comma; &NewLine; nextKey &equals; if &lpar;nextPageNumber &lt&semi; response&period;totalPages&rpar; nextPageNumber &plus; 1 else null &NewLine; &rpar; &NewLine; &rcub; catch &lpar;e&colon; Exception&rpar; &lbrace; &NewLine; LoadResult&period;Error&lpar;e&rpar; &NewLine; &rcub; &NewLine; &rcub; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p><span style&equals;"color&colon; &num;008000&semi;"><strong>LoadResult<&sol;strong><&sol;span> can take one of the following types&colon;<&sol;p>&NewLine;<&excl;-- WP QUADS Content Ad Plugin v&period; 2&period;0&period;98&period;1 -->&NewLine;<div class&equals;"quads-location quads-ad2" id&equals;"quads-ad2" style&equals;"float&colon;none&semi;margin&colon;0px&semi;">&NewLine;&NewLine;<&sol;div>&NewLine; &NewLine; &NewLine; &NewLine; &NewLine;<ul> &NewLine;<li><strong><span style&equals;"color&colon; &num;0000ff&semi;">LoadResult&period;Page&colon;<&sol;span><&sol;strong><span style&equals;"color&colon; &num;0000ff&semi;"><span style&equals;"color&colon; &num;000000&semi;"> If the result is successful&comma; return the loaded data wrapped in a <strong>LoadResult&period;Page<&sol;strong> object together with information about next and previous keys&period;<&sol;span><&sol;span> &NewLine; &NewLine;<&sol;li> &NewLine;<li><strong><span style&equals;"color&colon; &num;0000ff&semi;">LoadResult&period;Error&colon;<&sol;span><&sol;strong><span style&equals;"color&colon; &num;0000ff&semi;"><span style&equals;"color&colon; &num;000000&semi;"> If the request fails&comma; return the exception wrapped in a <strong>LoadResult&period;Error<&sol;strong> object containing info about the exception&period;<&sol;span><&sol;span><&sol;li> &NewLine;<&sol;ul> &NewLine; &NewLine; &NewLine; &NewLine;<h4 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong class&equals;"id iz">Pager and PagingData<&sol;strong><&sol;span><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>The container for the data returned from PagingSource is called <span style&equals;"color&colon; &num;008000&semi;"><strong>PagingData<&sol;strong><&sol;span>&period; A new instance of PagingData is created every time your data is refreshed &lpar;pulled from the network&rpar;&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<p>A <strong><span style&equals;"color&colon; &num;008000&semi;">Pager<&sol;span><&sol;strong> instance has to be created to build a PagingData stream&comma; using a <span style&equals;"color&colon; &num;008000&semi;"><strong>PagingConfig<&sol;strong><&sol;span> configuration object and a function that tells the <strong><span style&equals;"color&colon; &num;008000&semi;">Pager<&sol;span><&sol;strong> how to get an instance of your <strong><span style&equals;"color&colon; &num;008000&semi;">PagingSource<&sol;span><&sol;strong> implementation &period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">class PassengersViewModel&lpar; &NewLine; private val api&colon; MyApi &NewLine;&rpar; &colon; ViewModel&lpar;&rpar; &lbrace; &NewLine; val passengers &equals; &NewLine; Pager&lpar;config &equals; PagingConfig&lpar;pageSize &equals; 10&rpar;&comma; pagingSourceFactory &equals; &lbrace; &NewLine; PassengersDataSource&lpar;api&rpar; &NewLine; &rcub;&rpar;&period;flow&period;cachedIn&lpar;viewModelScope&rpar; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p>The Pager instance takes the below parameter&colon;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<ul class&equals;"wp-block-list"> &NewLine;<li><span style&equals;"color&colon; &num;008000&semi;"><strong>PagingSource<&sol;strong><&sol;span> is our data source created in the name <strong>PassengersDataSource<&sol;strong>&period;<&sol;li> &NewLine;<li><strong><span style&equals;"color&colon; &num;008000&semi;">PagingConfig<&sol;span><&sol;strong> defines how to get data from the PagingSource like page size &lpar;the number of items loaded at once from the PagingSource&rpar;&period;<&sol;li> &NewLine;<&sol;ul> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>Pager&period;flow<&sol;strong><&sol;span> &colon; will convert the stream of data into a Flow&lt&semi;PagingData&lt&semi;Passenger&gt&semi;&gt&semi;&period;<&sol;p> &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">cachedIn&lpar;&rpar;<&sol;span><&sol;strong> &colon; is used to persist the data beyond configuration changes&period; The best place to do this in a ViewModel&comma; using the viewModelScope&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine; &NewLine; &NewLine;<p>As we are passing a parameter inside our ViewModel&comma; we also need to create a <span id&equals;"crayon-617a3c3f1489f470854076" class&equals;"crayon-syntax crayon-syntax-inline crayon-theme-coda-special-board crayon-theme-coda-special-board-inline crayon-font-consolas"><span class&equals;"crayon-pre crayon-code"><span class&equals;"crayon-v">ViewModelFactory<&sol;span><&sol;span><&sol;span> &period;<&sol;p> &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">PassengersViewModelFactory&period;kt<&sol;span><&sol;strong><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">class PassengersViewModelFactory&lpar; &NewLine; private val api&colon; MyApi &NewLine;&rpar; &colon; ViewModelProvider&period;NewInstanceFactory&lpar;&rpar;&lbrace; &NewLine; &NewLine; override fun &lt&semi;T &colon; ViewModel&quest;&gt&semi; create&lpar;modelClass&colon; Class&lt&semi;T&gt&semi;&rpar;&colon; T &lbrace; &NewLine; return PassengersViewModel&lpar;api&rpar; as T &NewLine; &rcub; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<h4 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong>PagingDataAdapter<&sol;strong><&sol;span><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>To connect a RecyclerView to the PagingData&comma; implement a <span style&equals;"color&colon; &num;008000&semi;"><strong>PagingDataAdapter<&sol;strong><&sol;span>&colon;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">class PassengersAdapter &colon; &NewLine; PagingDataAdapter&lt&semi;Passenger&comma; PassengersAdapter&period;PassengersViewHolder&gt&semi;&lpar;PassengersComparator&rpar; &lbrace; &NewLine; &NewLine; override fun onCreateViewHolder&lpar; &NewLine; parent&colon; ViewGroup&comma; &NewLine; viewType&colon; Int &NewLine; &rpar;&colon; PassengersViewHolder &lbrace; &NewLine; return PassengersViewHolder&lpar; &NewLine; ItemPassengerBinding&period;inflate&lpar; &NewLine; LayoutInflater&period;from&lpar;parent&period;context&rpar;&comma; parent&comma; false &NewLine; &rpar; &NewLine; &rpar; &NewLine; &rcub; &NewLine; &NewLine; override fun onBindViewHolder&lpar;holder&colon; PassengersViewHolder&comma; position&colon; Int&rpar; &lbrace; &NewLine; val item &equals; getItem&lpar;position&rpar; &NewLine; item&quest;&period;let &lbrace; holder&period;bindPassenger&lpar;it&rpar; &rcub; &NewLine; &rcub; &NewLine; &NewLine; inner class PassengersViewHolder&lpar;private val binding&colon; ItemPassengerBinding&rpar; &colon; &NewLine; RecyclerView&period;ViewHolder&lpar;binding&period;root&rpar; &lbrace; &NewLine; &NewLine; fun bindPassenger&lpar;item&colon; Passenger&rpar; &equals; with&lpar;binding&rpar; &lbrace; &NewLine; imageViewAirlinesLogo&period;loadImage&lpar;item&period;airline&period;get&lpar;0&rpar;&period;logo&rpar; &NewLine; textViewHeadquarters&period;text &equals; item&period;airline&period;get&lpar;0&rpar;&period;head&lowbar;quaters &NewLine; textViewNameWithTrips&period;text &equals; "&dollar;&lbrace;item&period;name&rcub;&comma; &dollar;&lbrace;item&period;trips&rcub; Trips" &NewLine; &rcub; &NewLine; &rcub; &NewLine; &NewLine; object PassengersComparator &colon; DiffUtil&period;ItemCallback&lt&semi;Passenger&gt&semi;&lpar;&rpar; &lbrace; &NewLine; override fun areItemsTheSame&lpar;oldItem&colon; Passenger&comma; newItem&colon; Passenger&rpar;&colon; Boolean &lbrace; &NewLine; return oldItem&period;&lowbar;id &equals;&equals; newItem&period;&lowbar;id &NewLine; &rcub; &NewLine; &NewLine; override fun areContentsTheSame&lpar;oldItem&colon; Passenger&comma; newItem&colon; Passenger&rpar;&colon; Boolean &lbrace; &NewLine; return oldItem &equals;&equals; newItem &NewLine; &rcub; &NewLine; &rcub; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<ul> &NewLine;<li class&equals;"hq hr dm hs b ht lm hv hw hx ln hz ia ib lo id ie if lp ih ii ij lq il im in lf lg lh ej" data-selectable-paragraph&equals;"">The <strong><span style&equals;"color&colon; &num;008000&semi;">PagingDataAdapter<&sol;span><&sol;strong> listens to internal <span style&equals;"color&colon; &num;008000&semi;"><strong>PagingData<&sol;strong><&sol;span> loading events as pages are loaded and uses <span style&equals;"color&colon; &num;008000&semi;"><strong>DiffUtil<&sol;strong><&sol;span> on a background thread to compute fine-grained updates as updated content is received in the form of new <span style&equals;"color&colon; &num;008000&semi;"><strong>PagingData<&sol;strong><&sol;span> objects&period;<&sol;li> &NewLine;<&sol;ul> &NewLine;<p>The <strong><span style&equals;"color&colon; &num;008000&semi;">item&lowbar;passenger&period;xml<&sol;span><&sol;strong> defines the layout of recyclerView item&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>item&lowbar;passenger&period;xml<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">&lt&semi;&quest;xml version&equals;"1&period;0" encoding&equals;"utf-8"&quest;&gt&semi; &NewLine;&lt&semi;LinearLayout xmlns&colon;android&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res&sol;android" &NewLine; xmlns&colon;tools&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;tools" &NewLine; android&colon;layout&lowbar;width&equals;"match&lowbar;parent" &NewLine; android&colon;layout&lowbar;height&equals;"wrap&lowbar;content" &NewLine; android&colon;orientation&equals;"vertical" &NewLine; android&colon;padding&equals;"12dp"&gt&semi; &NewLine; &NewLine; &lt&semi;ImageView &NewLine; android&colon;id&equals;"&commat;&plus;id&sol;image&lowbar;view&lowbar;airlines&lowbar;logo" &NewLine; android&colon;layout&lowbar;width&equals;"280dp" &NewLine; android&colon;layout&lowbar;height&equals;"52dp" &NewLine; android&colon;layout&lowbar;gravity&equals;"center&lowbar;horizontal" &sol;&gt&semi; &NewLine; &NewLine; &lt&semi;TextView &NewLine; android&colon;id&equals;"&commat;&plus;id&sol;text&lowbar;view&lowbar;headquarters" &NewLine; android&colon;layout&lowbar;width&equals;"wrap&lowbar;content" &NewLine; android&colon;layout&lowbar;height&equals;"wrap&lowbar;content" &NewLine; android&colon;layout&lowbar;gravity&equals;"center&lowbar;horizontal" &NewLine; android&colon;layout&lowbar;marginTop&equals;"12dp" &NewLine; android&colon;textAlignment&equals;"center" &NewLine; android&colon;textColor&equals;"&commat;android&colon;color&sol;holo&lowbar;blue&lowbar;dark" &NewLine; android&colon;textSize&equals;"14sp" &NewLine; tools&colon;text&equals;"Jom Phol Subdistrict&comma; Chatuchak&comma; Bangkok&comma; Thailand" &sol;&gt&semi; &NewLine; &NewLine; &lt&semi;TextView &NewLine; android&colon;id&equals;"&commat;&plus;id&sol;text&lowbar;view&lowbar;name&lowbar;with&lowbar;trips" &NewLine; android&colon;layout&lowbar;width&equals;"match&lowbar;parent" &NewLine; android&colon;layout&lowbar;height&equals;"wrap&lowbar;content" &NewLine; android&colon;layout&lowbar;marginTop&equals;"12dp" &NewLine; android&colon;gravity&equals;"center&lowbar;horizontal" &NewLine; android&colon;textAlignment&equals;"center" &NewLine; android&colon;textColor&equals;"&commat;android&colon;color&sol;holo&lowbar;orange&lowbar;dark" &NewLine; android&colon;textSize&equals;"22sp" &NewLine; tools&colon;text&equals;"Dodi Papagena&comma; 2223 Trips" &sol;&gt&semi; &NewLine; &NewLine; &lt&semi;View &NewLine; android&colon;layout&lowbar;width&equals;"match&lowbar;parent" &NewLine; android&colon;layout&lowbar;height&equals;"1dp" &NewLine; android&colon;layout&lowbar;marginTop&equals;"8dp" &NewLine; android&colon;alpha&equals;"0&period;3" &NewLine; android&colon;background&equals;"&commat;android&colon;color&sol;holo&lowbar;red&lowbar;dark" &sol;&gt&semi; &NewLine; &NewLine;&lt&semi;&sol;LinearLayout&gt&semi;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p>The <span style&equals;"color&colon; &num;008000&semi;"><strong>activity&lowbar;main&period;xml<&sol;strong><&sol;span> defines the layout of MainActivity&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>activity&lowbar;main&period;xml<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">&lt&semi;&quest;xml version&equals;"1&period;0" encoding&equals;"utf-8"&quest;&gt&semi; &NewLine;&lt&semi;androidx&period;constraintlayout&period;widget&period;ConstraintLayout xmlns&colon;android&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res&sol;android" &NewLine; xmlns&colon;app&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res-auto" &NewLine; xmlns&colon;tools&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;tools" &NewLine; android&colon;layout&lowbar;width&equals;"match&lowbar;parent" &NewLine; android&colon;layout&lowbar;height&equals;"match&lowbar;parent" &NewLine; tools&colon;context&equals;"&period;ui&period;MainActivity"&gt&semi; &NewLine; &NewLine; &lt&semi;androidx&period;recyclerview&period;widget&period;RecyclerView &NewLine; android&colon;id&equals;"&commat;&plus;id&sol;recyclerView" &NewLine; android&colon;layout&lowbar;width&equals;"match&lowbar;parent" &NewLine; android&colon;layout&lowbar;height&equals;"match&lowbar;parent" &NewLine; app&colon;layout&lowbar;constraintBottom&lowbar;toBottomOf&equals;"parent" &NewLine; app&colon;layout&lowbar;constraintEnd&lowbar;toEndOf&equals;"parent" &NewLine; app&colon;layout&lowbar;constraintStart&lowbar;toStartOf&equals;"parent" &NewLine; app&colon;layout&lowbar;constraintTop&lowbar;toTopOf&equals;"parent" &NewLine; tools&colon;listitem&equals;"&commat;layout&sol;item&lowbar;passenger" &sol;&gt&semi; &NewLine; &NewLine;&lt&semi;&sol;androidx&period;constraintlayout&period;widget&period;ConstraintLayout&gt&semi;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p>Now&comma; in <strong><span style&equals;"color&colon; &num;008000&semi;">MainActivity&period;kt<&sol;span><&sol;strong> collect the <span style&equals;"color&colon; &num;008000&semi;"><strong>Flow&lt&semi;PagingData&gt&semi;<&sol;strong><&sol;span> and submit it to the <strong><span style&equals;"color&colon; &num;008000&semi;">PagingDataAdapter<&sol;span><&sol;strong>&period;<&sol;p> &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">MainActivity&period;kt<&sol;span><&sol;strong><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">class MainActivity &colon; AppCompatActivity&lpar;&rpar; &lbrace; &NewLine; &NewLine; lateinit var passengersViewModel&colon; PassengersViewModel &NewLine; lateinit var passengersAdapter&colon; PassengersAdapter &NewLine; private lateinit var binding&colon; ActivityMainBinding &NewLine; &NewLine; override fun onCreate&lpar;savedInstanceState&colon; Bundle&quest;&rpar; &lbrace; &NewLine; super&period;onCreate&lpar;savedInstanceState&rpar; &NewLine; binding &equals; ActivityMainBinding&period;inflate&lpar;layoutInflater&rpar; &NewLine; &NewLine; setContentView&lpar;binding&period;root&rpar; &NewLine; &NewLine; setupViewModel&lpar;&rpar; &NewLine; setupView&lpar;&rpar; &NewLine; setupList&lpar;&rpar; &NewLine; &rcub; &NewLine; &NewLine; private fun setupViewModel&lpar;&rpar; &lbrace; &NewLine; val factory &equals; PassengersViewModelFactory&lpar;MyApi&lpar;&rpar;&rpar; &NewLine; passengersViewModel &equals; ViewModelProvider&lpar;this&comma; factory&rpar;&period;get&lpar;PassengersViewModel&colon;&colon;class&period;java&rpar; &NewLine; &rcub; &NewLine; &NewLine; private fun setupView&lpar;&rpar; &lbrace; &NewLine; passengersAdapter &equals; PassengersAdapter&lpar;&rpar; &NewLine; binding&period;recyclerView&period;apply &lbrace; &NewLine; layoutManager &equals; LinearLayoutManager&lpar;context&rpar; &NewLine; adapter &equals; passengersAdapter &NewLine; setHasFixedSize&lpar;true&rpar; &NewLine; &rcub; &NewLine; &rcub; &NewLine; &NewLine; private fun setupList&lpar;&rpar; &lbrace; &NewLine; lifecycleScope&period;launch &lbrace; &NewLine; passengersViewModel&period;passengers&period;collectLatest &lbrace; pagedData -&gt&semi; &NewLine; passengersAdapter&period;submitData&lpar;pagedData&rpar; &NewLine; &rcub; &NewLine; &rcub; &NewLine; &rcub; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p>When you run the app it will look like this&colon;<&sol;p> &NewLine;<p><img class&equals;"alignnone wp-image-2911" src&equals;"https&colon;&sol;&sol;c1ctech&period;com&sol;wp-content&sol;uploads&sol;2021&sol;10&sol;Screenshot&lowbar;20211026-152739&lowbar;JetpackPagingExp1-498x1024&period;jpg" alt&equals;"" width&equals;"322" height&equals;"662" &sol;><&sol;p> &NewLine;<h4 class&equals;"wp-block-heading"><span style&equals;"color&colon; &num;000080&semi;"><strong><span id&equals;"Displaying-LoadingError-State">Displaying Loading&sol;Error State<&sol;span><&sol;strong><&sol;span><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>The <span style&equals;"color&colon; &num;008000&semi;"><strong>item&lowbar;loading&lowbar;state&period;xml<&sol;strong><&sol;span>&comma; defines a layout for displaying Loading&sol;Error state&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>item&lowbar;loading&lowbar;state&period;xml<&sol;strong><&sol;span><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">&lt&semi;&quest;xml version&equals;"1&period;0" encoding&equals;"utf-8"&quest;&gt&semi; &NewLine;&lt&semi;LinearLayout xmlns&colon;android&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res&sol;android" &NewLine; xmlns&colon;tools&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;tools" &NewLine; android&colon;layout&lowbar;width&equals;"match&lowbar;parent" &NewLine; android&colon;layout&lowbar;height&equals;"wrap&lowbar;content" &NewLine; android&colon;orientation&equals;"vertical" &NewLine; android&colon;padding&equals;"12dp"&gt&semi; &NewLine; &NewLine; &lt&semi;ProgressBar &NewLine; android&colon;id&equals;"&commat;&plus;id&sol;progressbar" &NewLine; android&colon;layout&lowbar;width&equals;"32dp" &NewLine; android&colon;layout&lowbar;height&equals;"32dp" &NewLine; android&colon;layout&lowbar;gravity&equals;"center&lowbar;horizontal" &sol;&gt&semi; &NewLine; &NewLine; &lt&semi;TextView &NewLine; android&colon;id&equals;"&commat;&plus;id&sol;text&lowbar;view&lowbar;error" &NewLine; android&colon;layout&lowbar;width&equals;"match&lowbar;parent" &NewLine; android&colon;layout&lowbar;height&equals;"wrap&lowbar;content" &NewLine; android&colon;gravity&equals;"center&lowbar;horizontal" &NewLine; android&colon;textAlignment&equals;"center" &NewLine; android&colon;textColor&equals;"&commat;android&colon;color&sol;holo&lowbar;red&lowbar;dark" &NewLine; android&colon;textSize&equals;"14sp" &NewLine; android&colon;visibility&equals;"gone" &NewLine; tools&colon;text&equals;"Some Error Occurred" &NewLine; tools&colon;visibility&equals;"visible" &sol;&gt&semi; &NewLine; &NewLine; &lt&semi;TextView &NewLine; android&colon;id&equals;"&commat;&plus;id&sol;button&lowbar;retry" &NewLine; android&colon;layout&lowbar;width&equals;"wrap&lowbar;content" &NewLine; android&colon;layout&lowbar;height&equals;"wrap&lowbar;content" &NewLine; android&colon;layout&lowbar;gravity&equals;"center&lowbar;horizontal" &NewLine; android&colon;layout&lowbar;marginTop&equals;"12dp" &NewLine; android&colon;text&equals;"Tap to Retry" &NewLine; android&colon;textAllCaps&equals;"false" &NewLine; android&colon;textColor&equals;"&commat;android&colon;color&sol;holo&lowbar;green&lowbar;dark" &NewLine; android&colon;textSize&equals;"16sp" &sol;&gt&semi; &NewLine; &NewLine;&lt&semi;&sol;LinearLayout&gt&semi;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<h4><span style&equals;"color&colon; &num;000080&semi;"><strong>LoadStateAdapter<&sol;strong><&sol;span><&sol;h4> &NewLine; &NewLine; &NewLine; &NewLine;<p>The class <strong><span style&equals;"color&colon; &num;008000&semi;">PassengersLoadStateAdapter<&sol;span><&sol;strong> extends LoadStateAdapter class&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">PassengersLoadStateAdapter&period;kt<&sol;span><&sol;strong><&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">class PassengersLoadStateAdapter&lpar; &NewLine; private val retry&colon; &lpar;&rpar; -&gt&semi; Unit &NewLine;&rpar; &colon; LoadStateAdapter&lt&semi;PassengersLoadStateAdapter&period;PassengerLoadStateViewHolder&gt&semi;&lpar;&rpar; &lbrace; &NewLine; &NewLine; inner class PassengerLoadStateViewHolder&lpar; &NewLine; private val binding&colon; ItemLoadingStateBinding&comma; &NewLine; private val retry&colon; &lpar;&rpar; -&gt&semi; Unit &NewLine; &rpar; &colon; RecyclerView&period;ViewHolder&lpar;binding&period;root&rpar; &lbrace; &NewLine; fun bind&lpar;loadState&colon; LoadState&rpar; &lbrace; &NewLine; if &lpar;loadState is LoadState&period;Error&rpar; &lbrace; &NewLine; binding&period;textViewError&period;text &equals; loadState&period;error&period;localizedMessage &NewLine; &rcub; &NewLine; &NewLine; binding&period;progressbar&period;visible&lpar;loadState is LoadState&period;Loading&rpar; &NewLine; binding&period;buttonRetry&period;visible&lpar;loadState is LoadState&period;Error&rpar; &NewLine; binding&period;textViewError&period;visible&lpar;loadState is LoadState&period;Error&rpar; &NewLine; binding&period;buttonRetry&period;setOnClickListener &lbrace; &NewLine; retry&lpar;&rpar; &NewLine; &rcub; &NewLine; &NewLine; binding&period;progressbar&period;visibility &equals; View&period;VISIBLE &NewLine; &rcub; &NewLine; &rcub; &NewLine; &NewLine; override fun onBindViewHolder&lpar;holder&colon; PassengerLoadStateViewHolder&comma; loadState&colon; LoadState&rpar; &lbrace; &NewLine; holder&period;bind&lpar;loadState&rpar; &NewLine; &rcub; &NewLine; &NewLine; override fun onCreateViewHolder&lpar; &NewLine; parent&colon; ViewGroup&comma; &NewLine; loadState&colon; LoadState &NewLine; &rpar; &equals; PassengerLoadStateViewHolder&lpar; &NewLine; ItemLoadingStateBinding&period;inflate&lpar;LayoutInflater&period;from&lpar;parent&period;context&rpar;&comma; parent&comma; false&rpar;&comma; &NewLine; retry &NewLine; &rpar; &NewLine;&rcub;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<h4><strong><span style&equals;"color&colon; &num;000080&semi;">Using LoadStateAdapter<&sol;span><&sol;strong><&sol;h4> &NewLine;<p>Now to add the LoadStateAdapter to our passengersAdapter&comma; we will use the function <strong><span style&equals;"color&colon; &num;008000&semi;">withLoadStateHeaderAndFooter<&sol;span><&sol;strong>&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<pre class&equals;"wp-block-preformatted">binding&period;recyclerView&period;adapter &equals; passengersAdapter&period;withLoadStateHeaderAndFooter&lpar; &NewLine; header &equals; PassengersLoadStateAdapter &lbrace; passengersAdapter&period;retry&lpar;&rpar; &rcub;&comma; &NewLine; footer &equals; PassengersLoadStateAdapter &lbrace; passengersAdapter&period;retry&lpar;&rpar; &rcub; &NewLine; &rpar;<&sol;pre> &NewLine; &NewLine; &NewLine; &NewLine;<p>Run your app and you will see the loading state or error state if occurred&comma; you will also get a retry button &lpar;when network is off&rpar;&period;<&sol;p> &NewLine;<p><img class&equals;"alignnone wp-image-2908" src&equals;"https&colon;&sol;&sol;c1ctech&period;com&sol;wp-content&sol;uploads&sol;2021&sol;10&sol;Screenshot&lowbar;20211028-152635&lowbar;JetpackPagingExp1-498x1024&period;jpg" alt&equals;"" width&equals;"322" height&equals;"663" &sol;>      <img class&equals;"alignnone wp-image-2909" src&equals;"https&colon;&sol;&sol;c1ctech&period;com&sol;wp-content&sol;uploads&sol;2021&sol;10&sol;Screenshot&lowbar;20211028-152708&lowbar;JetpackPagingExp1-498x1024&period;jpg" alt&equals;"" width&equals;"321" height&equals;"660" &sol;><&sol;p> &NewLine;<p>&nbsp&semi;<&sol;p> &NewLine;&NewLine;

Exit mobile version