<h3><span style="color: #000080;">Paging Library</span></h3>
<p>Announced with new additions at Google IO 2018, the Paging Library is a part of <span style="color: #008000;"><strong>Android</strong> <strong>Jetpack</strong></span>. The Paging Library makes it easier for you to load data gradually and gracefully within your app&#8217;s <span style="color: #008000;"><strong>RecyclerView</strong></span>.</p>
<p>The Paging Library helps your app observe and display a reasonable subset of this data. This functionality has several advantages:</p>
<ul>
<li>Data requests consume less network bandwidth and fewer system resources. Users who have metered or small data plans appreciate such data-conscious apps.</li>
<li>Even during data updates and refreshes, the app continues to respond quickly to user input.</li>
</ul>
<p>Get <span style="color: #000080;"><strong>GITHUB</strong></span> code from <a href="https://github.com/arunk7839/PagingExampleUsingRoom"><strong><span style="color: #00ff00;">HERE</span></strong></a>.</p>
<p> ;</p>
<p><span class="embed-youtube" style="text-align:center; display: block;"><amp-youtube data-videoid="m9K6inkyXPo" data-param-rel="1" data-param-showsearch="0" data-param-showinfo="1" data-param-iv_load_policy="1" data-param-fs="1" data-param-hl="en-US" data-param-autohide="2" data-param-wmode="transparent" width="1200" height="675" layout="responsive"><a href="https://www.youtube.com/watch?v=m9K6inkyXPo" placeholder><amp-img src="https://i.ytimg.com/vi/m9K6inkyXPo/hqdefault.jpg" alt="YouTube Poster" layout="fill" object-fit="cover"><noscript><img src="https://i.ytimg.com/vi/m9K6inkyXPo/hqdefault.jpg" loading="lazy" decoding="async" alt="YouTube Poster"></noscript></amp-img></a></amp-youtube></span></p>
<p> ;</p>
<h3 id="toc_2"><span style="color: #000080;">Major Components</span></h3>
<p><strong><span style="color: #0000ff;">DataSource</span></strong></p>
<p>DataSource holds the content from the database and external sources such as network APIs and serves as a local storage for PagedLists. A PagedList is generated by LivePagedListBuilder with DataSourceFactory passed into it, optionally with configuration parameters. The PagedList will contain a duplication of the DataSource. This process limits a PagedList to hold only a snapshot of data but allows multiple PagedLists from a single DataSource.</p>
<p>The <strong><span style="color: #008000;">Room persistence library</span></strong> provides native support for dataSource associated with the Paging library. For a given query, Room allows you to return a <strong><span style="color: #008000;">DataSource.Factory</span></strong> from the DAO and handles the implementation of the <span style="color: #008000;"><strong>DataSource</strong></span> for you. For example :</p>
<pre><code>@Query("SELECT * FROM COUNTRIES")
public abstract DataSource.Factory<;Integer,Country>; getCountries();</code></pre>
<p> ;</p>
<p><strong><span style="color: #0000ff;">PagedList</span></strong></p>
<p>PagedList is the key component of the library. This component allows a RecyclerView to load a chunk of data from a DataSource.</p>
<p>PagedList is a collection that loads data in pages, asynchronously. A <strong><span style="color: #008000;">PagedList</span></strong> can be used to load data from sources you define, and present it easily in your UI with a <span style="color: #008000;"><strong>RecyclerView</strong></span>.</p>
<p> ;</p>
<p><span style="color: #0000ff;"><strong>PagedListAdapter</strong></span></p>
<p>PagedListAdapter is a <strong><span style="color: #008000;">RecyclerView.Adapter </span></strong>that presents paged data from PagedLists in a RecyclerView. <strong><span style="color: #008000;">PagedListAdapter</span></strong> listens to PagedList loading callbacks as pages are loaded, and uses <strong><span style="color: #008000;">DiffUtil</span></strong> to compute fine grained updates as new PagedLists are received and then display the list to user in your UI with a <strong><span style="color: #008000;">recyclerView</span></strong>.</p>
<p> ;</p>
<h3><span style="color: #000080;">1. Adding Components to your Project</span></h3>
<p id="add_architecture_components"><strong><span style="color: #0000ff;">Add Architecture Components</span></strong></p>
<p>To add Architechture Components in your app , open app&#8217;s <strong><span style="color: #008000;">build.gradle</span></strong> and add the following dependencies :</p>
<pre><code><span style="color: #008000;"><strong>// ViewModel and LiveData</strong></span>
implementation "android.arch.lifecycle:extensions:1.0.0"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0"

<strong><span style="color: #008000;">// Room</span></strong>
implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
<span style="color: #008000;"><strong>
// Paging</strong></span>
implementation "android.arch.paging:runtime:1.0.0-alpha4-1"</code><code>
</code></pre>
<h3></h3>
<h3><span style="color: #000080;">2. Create DataSource</span></h3>
<p><strong><span style="color: #0000ff;">Create Entity</span></strong></p>
<p>Represents a modal class whose objects we are going to store in our database. For each entity, a database table is created to hold the items. You must reference the entity class in the <strong><span style="color: #008000;">Database</span></strong> class.</p>
<p><span style="color: #008000;"><strong>Country.java</strong></span></p>
<pre><code>@Entity(tableName = TABLE_NAME)
public class Country {

 public static final String TABLE_NAME = "COUNTRIES";

 public static DiffCallback<;Country>; DIFF_CALLBACK = new DiffCallback<;Country>;() {
 @Override
 public boolean areItemsTheSame(@NonNull Country oldItem, @NonNull Country newItem) {
 return oldItem.id == newItem.id;
 }

 @Override
 public boolean areContentsTheSame(@NonNull Country oldItem, @NonNull Country newItem) {
 return oldItem.equals(newItem);
 }
 };


 @PrimaryKey(autoGenerate = true)
 public int id;

 public String countryName;


 @Override
 public String toString() {
 return "Country{" +
 "id=" + id +
 ", countryName='" + countryName + '\'' +
 '}';
 }

 @Override
 public boolean equals(Object obj) {
 if (obj == this)
 return true;

 Country country = (Country) obj;

 return country.id == this.id &;&; country.countryName == this.countryName;
 }
}</code></pre>
<p> ;</p>
<p><span style="color: #0000ff;"><strong>Create Dao(</strong></span><span style="color: #0000ff;"><strong>Data Access Objects</strong></span><span style="color: #0000ff;"><strong>)</strong></span></p>
<p>The <strong><span style="color: #008000;">DataSource.Factory</span></strong> (implemented by Room) creates the <span style="color: #008000;"><strong>DataSource</strong></span>. Then, <span style="color: #008000;"><strong>LivePagedListBuilder</strong></span> builds the <strong><span style="color: #008000;">LiveData<;PagedList>;</span></strong>, using the passed-in <strong><span style="color: #008000;">DataSource.Factory</span></strong> and <strong><span style="color: #008000;">PagedList</span></strong> configuration.</p>
<p> ;</p>
<pre><code>@Dao
public interface CountryDao {

 @Insert(onConflict = OnConflictStrategy.REPLACE)
 public void insertCountriesList(List<;Country>; countries);

 @Query("SELECT * FROM COUNTRIES")
 public abstract DataSource.Factory<;Integer,Country>; getCountries();
}</code></pre>
<p> ;</p>
<p><strong><span style="color: #0000ff;">Create Database</span></strong></p>
<p>By calling <span style="color: #008000;"><strong>getCountryDatabase()</strong></span> we get roomDatabase object using which we can get <strong><span style="color: #008000;">CountryDao</span></strong> instance to interact or query with database .</p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>

<pre><code>@Database(entities = {Country.class}, version = 1)
public abstract class CountryDatabase extends RoomDatabase {
 private static final String DB_NAME = "Country_Database.db";
 private static CountryDatabase INSTANCE;


 public static CountryDatabase getCountryDatabase(Context context) {
 if (INSTANCE == null) {
 INSTANCE = Room.databaseBuilder(context, CountryDatabase.class, DB_NAME).build();

 }
 return INSTANCE;
 }

 public static void destroyInstance() {
 INSTANCE = null;
 }

 public abstract CountryDao countryDao();
}</code></pre>
<h3></h3>
<h3><span style="color: #000080;">3. Create ViewModel</span></h3>
<p><code>LivePagedListBuilder</code>builds the <code>LiveData<;PagedList>;</code>, using the passed-in <code>DataSource.Factory</code>and <code>PagedList</code> configuration.</p>
<p>This <span style="color: #008000;"><strong>LivePagedListBuilder</strong></span> object is responsible for creating <strong><span style="color: #008000;">PagedList</span></strong> objects. When a PagedList is created the <strong><span style="color: #008000;">LiveData</span></strong> emits the new <strong><span style="color: #008000;">PagedList</span></strong> to the <span style="color: #008000;"><strong>ViewModel</strong></span>, which in turn passes it to the <strong><span style="color: #008000;">UI</span></strong>. The UI observes the changed PagedList and uses its <strong><span style="color: #008000;">PagedListAdapter</span></strong> to update the <strong><span style="color: #008000;">RecyclerView</span></strong> that presents the <span style="color: #000000;">PagedList</span> data.</p>
<p>To build and configure a <span style="color: #008000;"><strong>LiveData<;PagedList>;</strong></span>, use a <span style="color: #008000;"><strong>LivePagedListBuilder</strong></span>. Besides the <span style="color: #008000;"><strong>DataSource.Factory</strong></span>, you need to provide a <strong><span style="color: #008000;">PagedList</span></strong> configuration, which can include the following options:</p>
<ul>
<li>setPageSize(int) : the size of a page loaded by a <strong><span style="color: #008000;">PagedList</span></strong></li>
<li>setPrefetchDistance(int) : how far ahead to load</li>
<li>setInitialLoadSizeHint(int) : how many items to load when the first load occurs</li>
<li>setEnablePlaceholders(boolean) : whether null items to be added to the <strong><span style="color: #008000;">PagedList</span></strong>, to represent data that hasn&#8217;t been loaded yet.</li>
</ul>
<p> ;</p>
<pre><code>public class CountryViewModel extends AndroidViewModel {

 private CountryDatabase countryDatabase;

 public CountryDao countryDao;

 public LiveData<;PagedList<;Country>;>; countriesList;

 public CountryViewModel(@NonNull Application application) {
 super(application);

 countryDatabase = CountryDatabase.getCountryDatabase(this.getApplication());

 countryDao = countryDatabase.countryDao();

 }

 public void init(CountryDao countryDao) {
 PagedList.Config pagedListConfig =
 (new PagedList.Config.Builder()).setEnablePlaceholders(true)
 .setPrefetchDistance(10)
 .setPageSize(20).build();

 countriesList = (new LivePagedListBuilder(countryDao.getCountries()
 , pagedListConfig))
 .build();


 }

}</code></pre>
<p> ;</p>
<p>In the onCreate, we create the instance of <strong><span style="color: #008000;">ViewModel</span></strong>. In ViewModel class <strong><span style="color: #008000;">LiveData</span></strong> emits the new PagedList to the <strong><span style="color: #008000;">ViewModel</span></strong>. which in turn passes it to the <strong><span style="color: #008000;">UI</span></strong>. The UI observes the changed PagedList and uses its <strong><span style="color: #008000;">PagedListAdapter</span></strong> to update the <strong><span style="color: #008000;">RecyclerView</span></strong> that presents the PagedList data.</p>
<div id="crayon-5b3df81a4baa1738139756" class="crayon-syntax crayon-theme-github crayon-font-courier-new crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-mouseover">
<div class="crayon-plain-wrap"></div>
<div class="crayon-main">
<pre><code>@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 recyclerView = (RecyclerView) findViewById(R.id.countryList);


 recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));

 viewModel = ViewModelProviders.of(this).get(CountryViewModel.class);
 insertUser(viewModel.getCountryDatabase());

 viewModel.init(viewModel.countryDao);

 CountryAdapter countryAdapter = new CountryAdapter();

 viewModel.countriesList.observe(this, pageList ->; {
 countryAdapter.setList(pageList);
 });

 recyclerView.setAdapter(countryAdapter);

}</code></pre>
</div>
</div>
<h3></h3>
<h3><span style="color: #000080;">4. Create Adapter</span></h3>
<p>To bind a <strong><span style="color: #008000;">PagedList</span></strong> to a <span style="color: #008000;"><strong>RecyclerView</strong></span>, use a <strong><span style="color: #008000;">PagedListAdapter</span></strong>. The <strong><span style="color: #008000;">PagedListAdapter</span></strong> gets notified whenever the PagedList content is loaded and then signals the <strong><span style="color: #008000;">RecyclerView</span></strong> to update.</p>
<p>To tell the PagedListAdapter how to compute the difference between the two elements, you’ll need to implement a new class, <strong><span style="color: #008000;">DiffCallback</span> </strong>.Here, you will define two things as given below :</p>
<p><strong><span style="color: #008000;">areItemsTheSame</span></strong> :Checks whether both are reffering to the same item or not.</p>
<p><strong><span style="color: #008000;">areContentsTheSame</span></strong> : Checks whether the content of both item are same or not.</p>
<pre><code>public static DiffCallback<;Country>; DIFF_CALLBACK = new DiffCallback<;Country>;() {
 @Override
 public boolean areItemsTheSame(@NonNull Country oldItem, @NonNull Country newItem) {
 return oldItem.id == newItem.id;
 }

 @Override
 public boolean areContentsTheSame(@NonNull Country oldItem, @NonNull Country newItem) {
 return oldItem.equals(newItem);
 }
};

@Override
public boolean equals(Object obj) {
 if (obj == this)
 return true;

 Country country = (Country) obj;

 return country.id == this.id &;&; country.countryName == this.countryName;
}</code></pre>
<p> ;</p>
<p>Let’s look at the adapter.So our adapter would extend <strong><span style="color: #008000;">PagedListAdapter</span></strong>, Here We define the callback, the <strong><span style="color: #008000;">DIFF_CALLBACK</span></strong>, for our country objects and then <span style="color: #008000;"><strong>onBindViewHolder()</strong></span> binds the PagedList items to the ViewHolder one by one.</p>
<pre><code>public class CountryAdapter extends PagedListAdapter<;Country, CountryAdapter.CountryViewHolder>; {

 public CountryAdapter() {
 super(Country.DIFF_CALLBACK);
 }


 @NonNull
 @Override
 public CountryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 View v = LayoutInflater.from(parent.getContext())
 .inflate(R.layout.item_country_list, parent, false);

 return new CountryViewHolder(v);

 }

 @Override
 public void onBindViewHolder(@NonNull CountryViewHolder holder, int position) {
 Country country = getItem(position);
 if (country != null) {
 holder.bindTo(country);
 }

 }


 public static class CountryViewHolder extends RecyclerView.ViewHolder {

 TextView countryName;
 TextView uniqueId;


 public CountryViewHolder(View itemView) {
 super(itemView);

 countryName = (TextView) itemView.findViewById(R.id.tv_country);
 uniqueId = (TextView) itemView.findViewById(R.id.tv_id);
 }

 public void bindTo(Country country) {
 countryName.setText(country.countryName);
 uniqueId.setText(Integer.toString(country.id));
 }
 }


}</code></pre>
<p> ;</p>
<p> ;</p>


