web-dev-qa-db-fra.com

Bibliothèque de pagination sans pièce

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;
    }

}
7
Idee

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

7
Ritesh Chandnani

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 .

2
Kashfa Khan