0

アーキテクチャコンポーネントの新しいandroid Paging Libraryを使用して、より多くのアイテムをサーバーにリクエストする方法を知りたいですか?たとえば、サーバーからデータがロードされるエンドレススクロールを実装したい場合、どのようにアイテムをさらにリクエストする必要があるかを知ることができます。Androidのページングライブラリで、無制限のスクロール時にアイテムを追加する場合

答えて

1

私は、この機能を実装するための次のクラスを使用します。

package com.mlsdev.enjoymusic.data.repository; 

import android.arch.paging.DataSource; 
import android.arch.paging.TiledDataSource; 
import android.arch.persistence.room.InvalidationTracker; 
import android.support.annotation.NonNull; 
import android.support.annotation.WorkerThread; 
import android.util.Log; 

import com.mlsdev.enjoymusic.data.local.DeezerDatabase; 
import com.mlsdev.enjoymusic.data.local.Table; 

import java.io.IOException; 
import java.util.List; 
import java.util.Set; 

import retrofit2.Call; 
import retrofit2.Response; 

/** 
* Created by stafievsky on 09.10.17. 
*/ 

public abstract class PagedNetworkBoundResource<ResultType, RequestType> extends TiledDataSource<ResultType> { 

    private final InvalidationTracker.Observer mObserver; 
    private DeezerDatabase db; 

    public PagedNetworkBoundResource(DeezerDatabase db) { 
     this.db = db; 
     mObserver = new InvalidationTracker.Observer(Table.States.PLAY_STATE) { 

      public void onInvalidated(@NonNull Set<String> tables) { 
       invalidate(); 
      } 
     }; 
     this.db.getInvalidationTracker().addWeakObserver(mObserver); 
    } 


    @Override 
    public boolean isInvalid() { 
     db.getInvalidationTracker().refreshVersionsSync(); 
     return super.isInvalid(); 
    } 

    @Override 
    public int countItems() { 
     return DataSource.COUNT_UNDEFINED; 
    } 

    @Override 
    public List<ResultType> loadRange(int startPosition, int count) { 
     if (startPosition == 0 && count == 20) { 
      clearDB(); 
     } 
     fetchFromNetwork(startPosition, count); 
     return loadFromDb(startPosition, count); 
    } 

    public abstract void clearDB(); 

    @WorkerThread 
    private void fetchFromNetwork(int startPosition, int count) { 
     if (createCall(startPosition, count) != null) 
      try { 
       Response<RequestType> response = createCall(startPosition, count).execute(); 
       if (response.isSuccessful() && response.code() == 200) { 
        saveCallResult(response.body()); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
    } 

    @WorkerThread 
    protected abstract void saveCallResult(@NonNull RequestType item); 


    @WorkerThread 
    protected abstract List<ResultType> loadFromDb(int startPosition, int count); 

    @WorkerThread 
    protected abstract Call<RequestType> createCall(int startPosition, int count); 
} 

そして、このクラスのこのインプリメンテーション:

public LiveData<PagedList<ChartAlbumDao.Album>> getAlbums() { 

    return new LivePagedListProvider<Integer, ChartAlbumDao.Album>() { 
     @Override 
     protected DataSource<Integer, ChartAlbumDao.Album> createDataSource() { 
      return new PagedNetworkBoundResource<ChartAlbumDao.Album, ModelList<ChartAlbumEntity>>(db) { 

       @Override 
       public void clearDB() { 

       } 

       @Override 
       protected void saveCallResult(@NonNull ModelList<ChartAlbumEntity> item) { 
        if (item != null) { 
         chartAlbumDao.saveAlbums(item.getItems()); 
        } 
       } 

       @NonNull 
       @Override 
       protected List<ChartAlbumDao.Album> loadFromDb(int startPosition, int count) { 
        return chartAlbumDao.loadAlbums(count, startPosition); 
       } 

       @NonNull 
       @Override 
       protected Call<ModelList<ChartAlbumEntity>> createCall(int startPosition, int count) { 
        return deezerService.getChartAlbums(startPosition, count); 
       } 
      }; 
     } 

    }.create(0, new PagedList.Config.Builder() 
      .setEnablePlaceholders(false) 
      .setPageSize(20) 
      .setInitialLoadSizeHint(20) 
      .build()); 
} 
+0

がよさそうです。ありがとうございました! –

+0

データが無効化されると、再度loadRangeが呼び出されますか?その場合、データが再度フェッチされないようにするにはどうすればよいですか?そうでない場合、TiledDataSourceは更新するアイテムをどのように知っていますか? –

+0

そして、loadFromDbメソッドでは、データベースが初めて項目を持っていて、それがネットワークからフェッチされているために、項目がないとどうなりますか? loadRangeメソッドがcountより少ない項目を受け取った場合、ページされたリストはそれがリストの終わりであることを理解します。 –

関連する問題