blob: dbe58ebf15cf62a374e88dc8e654cff2abe0404e [file] [log] [blame]
<html devsite="true">
<head>
<title>PagedList.BoundaryCallback</title>
{% setvar book_path %}/reference/androidx/_book.yaml{% endsetvar %}
{% include "_shared/_reference-head-tags.html" %}
</head>
<body>
<h1>PagedList.BoundaryCallback</h1>
{% setvar page_path %}androidx/paging/PagedList.BoundaryCallback.html{% endsetvar %}
{% setvar can_switch %}1{% endsetvar %}
{% include "reference/_java_switcher2.md" %}
<p>
<pre>public abstract class PagedList.BoundaryCallback&lt;T&nbsp;extends&nbsp;<a href="/reference/java/lang/Object.html">Object</a>&gt;</pre>
</p>
<hr>
<p>Signals when a PagedList has reached the end of available data.</p>
<p>When local storage is a cache of network data, it's common to set up a streaming pipeline: Network data is paged into the database, database is paged into UI. Paging from the database to UI can be done with a <code>LiveData&lt;PagedList&gt;</code>, but it's still necessary to know when to trigger network loads.</p>
<p><code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html">BoundaryCallback</a></code> does this signaling - when a <code><a href="/reference/androidx/paging/PagingSource.html">PagingSource</a></code> runs out of data at the end of the list, <code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#onItemAtEndLoaded(kotlin.Any)">onItemAtEndLoaded</a></code> is called, and you can start an async network load that will write the result directly to the database. Because the database is being observed, the UI bound to the <code>LiveData&lt;PagedList&gt;</code> will update automatically to account for the new items.</p>
<p>Note that a BoundaryCallback instance shared across multiple PagedLists (e.g. when passed to <code><a href="/reference/androidx/paging/LivePagedListBuilder.html#setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback)">androidx.paging.LivePagedListBuilder.setBoundaryCallback</a></code>, the callbacks may be issued multiple times. If for example <code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#onItemAtEndLoaded(kotlin.Any)">onItemAtEndLoaded</a></code> triggers a network load, it should avoid triggering it again while the load is ongoing.</p>
<p>The database + network Repository in the <a href="https://github.com/googlesamples/android-architecture-components/blob/master/PagingWithNetworkSample/README.md">PagingWithNetworkSample</a> shows how to implement a network BoundaryCallback using <a href="https://square.github.io/retrofit/">Retrofit</a>, while handling swipe-to-refresh, network errors, and retry.</p>
<h3> Requesting Network Data</h3>
<p><code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html">BoundaryCallback</a></code> only passes the item at front or end of the list when out of data. This makes it an easy fit for item-keyed network requests, where you can use the item passed to the <code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html">BoundaryCallback</a></code> to request more data from the network. In these cases, the source of truth for next page to load is coming from local storage, based on what's already loaded.</p>
<p>If you aren't using an item-keyed network API, you may be using page-keyed, or page-indexed. If this is the case, the paging library doesn't know about the page key or index used in the <code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html">BoundaryCallback</a></code>, so you need to track it yourself. You can do this in one of two ways:</p>
<p>&lt;h5&gt;Local storage Page key&lt;/h5&gt; If you want to perfectly resume your query, even if the app is killed and resumed, you can store the key on disk. Note that with a positional/page index network API, there's a simple way to do this, by using the <code>listSize</code> as an input to the next load (or <code>listSize / NETWORK_PAGE_SIZE</code>, for page indexing).</p>
<p>The current list size isn't passed to the BoundaryCallback though. This is because the PagedList doesn't necessarily know the number of items in local storage. Placeholders may be disabled, or the <code><a href="/reference/androidx/paging/PagingSource.html">PagingSource</a></code> may not count total number of items.</p>
<p>Instead, for these positional cases, you can query the database for the number of items, and pass that to the network. &lt;h5&gt;In-Memory Page key&lt;/h5&gt; Often it doesn't make sense to query the next page from network if the last page you fetched was loaded many hours or days before. If you keep the key in memory, you can refresh any time you start paging from a network source.</p>
<p>Store the next key in memory, inside your BoundaryCallback. When you create a new BoundaryCallback when creating a new <code>LiveData</code>/<code>Observable</code> of <code>PagedList</code>, refresh data. For example, <a href="https://codelabs.developers.google.com/codelabs/android-paging/index.html#8">in the Paging Codelab</a>, the GitHub network page index is stored in memory.</p>
<div class="devsite-table-wrapper">
<table class="responsive">
<thead>
<tr>
<th colspan="2">Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&lt;T&nbsp;extends&nbsp;<a href="/reference/java/lang/Object.html">Object</a>&gt;</code></td>
<td width="100%">
<p>Type loaded by the <code><a href="/reference/androidx/paging/PagedList.html">PagedList</a></code>.</p>
</td>
</tr>
</tbody>
</table>
</div>
<h2>Summary</h2>
<div class="devsite-table-wrapper">
<table class="responsive">
<thead>
<tr>
<th colspan="2"><h3>Public constructors</h3></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div><code>&lt;T&nbsp;extends&nbsp;<a href="/reference/java/lang/Object.html">Object</a>&gt; <a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#BoundaryCallback()">BoundaryCallback</a>()</code></div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="devsite-table-wrapper">
<table class="responsive">
<thead>
<tr>
<th colspan="2"><h3>Public methods</h3></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>void</code></td>
<td width="100%">
<div><code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#onItemAtEndLoaded(kotlin.Any)">onItemAtEndLoaded</a>(T&nbsp;itemAtEnd)</code></div>
<p>Called when the item at the end of the PagedList has been loaded, and access has occurred within <code><a href="/reference/androidx/paging/PagedList.Config.html#prefetchDistance()">PagedList.Config.prefetchDistance</a></code> of it.</p>
</td>
</tr>
<tr>
<td><code>void</code></td>
<td width="100%">
<div><code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#onItemAtFrontLoaded(kotlin.Any)">onItemAtFrontLoaded</a>(T&nbsp;itemAtFront)</code></div>
<p>Called when the item at the front of the PagedList has been loaded, and access has occurred within <code><a href="/reference/androidx/paging/PagedList.Config.html#prefetchDistance()">PagedList.Config.prefetchDistance</a></code> of it.</p>
</td>
</tr>
<tr>
<td><code>void</code></td>
<td width="100%">
<div><code><a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#onZeroItemsLoaded()">onZeroItemsLoaded</a>()</code></div>
<p>Called when zero items are returned from an initial load of the PagedList's data source.</p>
</td>
</tr>
</tbody>
</table>
</div>
<h2>Public constructors</h2>
<div><a name="BoundaryCallback--"></a>
<h3 class="api-name" id="BoundaryCallback()">BoundaryCallback</h3>
<pre class="api-signature no-pretty-print">public&nbsp;final&nbsp;&lt;T&nbsp;extends&nbsp;<a href="/reference/java/lang/Object.html">Object</a>&gt; <a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#BoundaryCallback()">BoundaryCallback</a>()</pre>
<div class="devsite-table-wrapper">
<table class="responsive">
<thead>
<tr>
<th colspan="2">Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&lt;T&nbsp;extends&nbsp;<a href="/reference/java/lang/Object.html">Object</a>&gt;</code></td>
<td width="100%">
<p>Type loaded by the <code><a href="/reference/androidx/paging/PagedList.html">PagedList</a></code>.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h2>Public methods</h2>
<div><a name="onItemAtEndLoaded-kotlin.Any-"></a>
<h3 class="api-name" id="onItemAtEndLoaded(kotlin.Any)">onItemAtEndLoaded</h3>
<pre class="api-signature no-pretty-print">public&nbsp;void&nbsp;<a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#onItemAtEndLoaded(kotlin.Any)">onItemAtEndLoaded</a>(T&nbsp;itemAtEnd)</pre>
<p>Called when the item at the end of the PagedList has been loaded, and access has occurred within <code><a href="/reference/androidx/paging/PagedList.Config.html#prefetchDistance()">PagedList.Config.prefetchDistance</a></code> of it.</p>
<p>No more data will be appended to the <code><a href="/reference/androidx/paging/PagedList.html">PagedList</a></code> after this item.</p>
<div class="devsite-table-wrapper">
<table class="responsive">
<thead>
<tr>
<th colspan="2">Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>T&nbsp;itemAtEnd</code></td>
<td width="100%">
<p>The first item of <code><a href="/reference/androidx/paging/PagedList.html">PagedList</a></code></p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div><a name="onItemAtFrontLoaded-kotlin.Any-"></a>
<h3 class="api-name" id="onItemAtFrontLoaded(kotlin.Any)">onItemAtFrontLoaded</h3>
<pre class="api-signature no-pretty-print">public&nbsp;void&nbsp;<a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#onItemAtFrontLoaded(kotlin.Any)">onItemAtFrontLoaded</a>(T&nbsp;itemAtFront)</pre>
<p>Called when the item at the front of the PagedList has been loaded, and access has occurred within <code><a href="/reference/androidx/paging/PagedList.Config.html#prefetchDistance()">PagedList.Config.prefetchDistance</a></code> of it.</p>
<p>No more data will be prepended to the PagedList before this item.</p>
<div class="devsite-table-wrapper">
<table class="responsive">
<thead>
<tr>
<th colspan="2">Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>T&nbsp;itemAtFront</code></td>
<td width="100%">
<p>The first item of PagedList</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div><a name="onZeroItemsLoaded--"></a>
<h3 class="api-name" id="onZeroItemsLoaded()">onZeroItemsLoaded</h3>
<pre class="api-signature no-pretty-print">public&nbsp;void&nbsp;<a href="/reference/androidx/paging/PagedList.BoundaryCallback.html#onZeroItemsLoaded()">onZeroItemsLoaded</a>()</pre>
<p>Called when zero items are returned from an initial load of the PagedList's data source.</p>
</div>
</body>
</html>