Tous les exemples de la nouvelle bibliothèque de radiomessagerie ont été avec la bibliothèque de salle et Room crée une source de données pour nous. Dans mon cas, je dois créer ma source de données personnalisée.
Voici une méthode dans ma classe de modèle de vue qui doit renvoyer les données en direct. Mon Nail de données retourne toujours null.
LiveData<PagedList<ApiResult>> getData(){
LivePagedListProvider<Integer,ApiResult> p = new LivePagedListProvider<Integer, ApiResult>() {
@Override
protected DataSource<Integer, ApiResult> createDataSource() {
return new DataClass();
}
};
listLiveData = p.create(0,new PagedList.Config.Builder()
.setPageSize(5) //number of items loaded at once
.setPrefetchDistance(0)// the distance to the end of already loaded list before new data is loaded
.build());
return listLiveData;
}
Et voici la classe de données
public class DataClass extends TiledDataSource<ApiResult> {
private List<ApiResult> result = new ArrayList<>();
@Override
public int countItems() {
return result.size();
}
@Override
public List<ApiResult> loadRange(int startPosition, int count) {
Call<String> call = NetworkModule.providesWebService().makeRequest();
call.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
Log.i(DataClass.this.getClass().getSimpleName() + " - onResponse", String.valueOf(response));
result = parseJson(response.body());
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.i(DataClass.this.getClass().getSimpleName() + " - onFailure", t.getMessage());
}
});
return result;
}
}
Je pense que cela peut aider:
1. countItems () devrait renvoyer DataSource.COUNT_UNDEFINED
2. loadRange (int startPosition, int count): Vous pouvez exécuter directement votre requête.
3. Vous pouvez donc maintenant supprimer la variable globale de résultat
En outre, désactiver les espaces réservés:
listLiveData = p.create(0,new PagedList.Config.Builder()
.setPageSize(5) //number of items loaded at once
.setPrefetchDistance(10) //Must be >0 since placeholders are off
.setEnablePlaceholders(false)
.build());
Voici le code mis à jour pour Data Class:
public class DataClass extends TiledDataSource<ApiResult> {
@Override
public int countItems() {
return DataSource.COUNT_UNDEFINED;
}
@Override
public List<ApiResult> loadRange(int startPosition, int count) {
Call<String> call = NetworkModule.providesWebService().makeRequest();
Response<String> response = call.execute();
return parseJson(response.body());
}
Vous pouvez consulter un exemple de projet ici: https://github.com/brainail/.samples/tree/master/ArchPagingLibraryWithNetwork
Vous pouvez créer une source de données personnalisée. Nous avons généralement créé une API d’arrière-plan pour extraire les données qui prennent pagenumber en tant que paramètre pour renvoyer la page spécifiée.
Pour cette situation, vous pouvez utiliser PageKeyedDataSource. Voici un exemple de code de PageKeyedDataSource utilisant l'API StackOverflow. Le code ci-dessous utilise Retrofit pour obtenir les données de l'API StackOverflow.
public class ItemDataSource extends PageKeyedDataSource<Integer, Item> {
//the size of a page that we want
public static final int PAGE_SIZE = 50;
//we will start from the first page which is 1
private static final int FIRST_PAGE = 1;
//we need to fetch from stackoverflow
private static final String SITE_NAME = "stackoverflow";
//this will be called once to load the initial data
@Override
public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull final LoadInitialCallback<Integer, Item> callback) {
RetrofitClient.getInstance()
.getApi().getAnswers(FIRST_PAGE, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback<StackApiResponse>() {
@Override
public void onResponse(Call<StackApiResponse> call, Response<StackApiResponse> response) {
if (response.body() != null) {
callback.onResult(response.body().items, null, FIRST_PAGE + 1);
}
}
@Override
public void onFailure(Call<StackApiResponse> call, Throwable t) {
}
});
}
//this will load the previous page
@Override
public void loadBefore(@NonNull final LoadParams<Integer> params, @NonNull final LoadCallback<Integer, Item> callback) {
RetrofitClient.getInstance()
.getApi().getAnswers(params.key, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback<StackApiResponse>() {
@Override
public void onResponse(Call<StackApiResponse> call, Response<StackApiResponse> response) {
//if the current page is greater than one
//we are decrementing the page number
//else there is no previous page
Integer adjacentKey = (params.key > 1) ? params.key - 1 : null;
if (response.body() != null) {
//passing the loaded data
//and the previous page key
callback.onResult(response.body().items, adjacentKey);
}
}
@Override
public void onFailure(Call<StackApiResponse> call, Throwable t) {
}
});
}
//this will load the next page
@Override
public void loadAfter(@NonNull final LoadParams<Integer> params, @NonNull final LoadCallback<Integer, Item> callback) {
RetrofitClient.getInstance()
.getApi()
.getAnswers(params.key, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback<StackApiResponse>() {
@Override
public void onResponse(Call<StackApiResponse> call, Response<StackApiResponse> response) {
if (response.body() != null) {
//if the response has next page
//incrementing the next page number
Integer key = response.body().has_more ? params.key + 1 : null;
//passing the loaded data and next page value
callback.onResult(response.body().items, key);
}
}
@Override
public void onFailure(Call<StackApiResponse> call, Throwable t) {
}
});
}
}
Vous pouvez voir ici que nous obtenons le résultat en effectuant un appel de modification, puis que nous poussons le résultat à un rappel.
Pour une explication détaillée, étape par étape, passez par ceci Didacticiel de la bibliothèque de radiomessagerie Android .