Sayfalara ayrılmış verileri toplama

Bu kılavuz, Sayfalama Kitaplığı genel bakış, bu bilgileri nasıl uygulayacağınızı Uygulamanızın veri yükleme çözümünü, uygulamanızın mimarisine uyacak şekilde özelleştirin gerekiyor.

Gözlemlenebilir liste oluşturma

Genellikle, kullanıcı arayüzü kodunuzda LiveData<PagedList> nesne (veya, RxJava2 kullanıyorsanız bir Flowable<PagedList> veya Observable<PagedList> nesnesi) içerir. ViewModel. Bu gözlemlenebilir nesne ile bu sunumun içeriği arasında bir bağlantı uygulamanızın liste verileri.

Bu gözlemlenebilir öğelerden birini oluşturmak için PagedList nesne, bir şunun örneği: DataSource.Factory - bir LivePagedListBuilder veya RxPagedListBuilder nesnesini tanımlayın. DataSource nesnesi yüklenir tek bir PagedList için sayfa sayısı. Fabrika sınıfı, yeni iş kırılım yapısının Veritabanı tablosu geçersiz kılmaları gibi içerik güncellemelerine yanıt olarak PagedList yardımcı olabilir. Odada kalıcılık kitaplık, DataSource.Factory sağlayabilir kendiniz oluşturabilir veya kendi nesnelerinizi oluşturabilirsiniz.

Aşağıdaki kod snippet'i, LiveData<PagedList> uygulamanın ViewModel sınıfı şu uygulamayı kullanıyor: Odanın DataSource.Factory-bina özellikler:

KonserDao

Kotlin

@Dao
interface ConcertDao {
    // The Int type parameter tells Room to use a PositionalDataSource
    // object, with position-based loading under the hood.
    @Query("SELECT * FROM concerts ORDER BY date DESC")
    fun concertsByDate(): DataSource.Factory<Int, Concert>
}

Java

@Dao
public interface ConcertDao {
    // The Integer type parameter tells Room to use a PositionalDataSource
    // object, with position-based loading under the hood.
    @Query("SELECT * FROM concerts ORDER BY date DESC")
    DataSource.Factory<Integer, Concert> concertsByDate();
}

KonserGörünümModeli

Kotlin

// The Int type argument corresponds to a PositionalDataSource object.
val myConcertDataSource : DataSource.Factory<Int, Concert> =
       concertDao.concertsByDate()

val concertList = myConcertDataSource.toLiveData(pageSize = 50)

Java

// The Integer type argument corresponds to a PositionalDataSource object.
DataSource.Factory<Integer, Concert> myConcertDataSource =
       concertDao.concertsByDate();

LiveData<PagedList<Concert>> concertList =
        LivePagedListBuilder(myConcertDataSource, /* page size */ 50).build();

Kendi sayfalama yapılandırmanızı tanımlayın

Daha fazla yapılandırmaya Gelişmiş için LiveData<PagedList> kendi sayfa oluşturma yapılandırmanızı da tanımlayabilirsiniz. Özellikle, şunları yapabilirsiniz: şu özellikleri tanımlayın:

  • Sayfa boyutu: Her sayfadaki öğe sayısı.
  • Önceden getirme mesafesi: Bir uygulamanın kullanıcı arayüzünde görünen son öğe göz önüne alındığında, öğe olarak gönderin. Bu değer sayfa boyutundan birkaç kat daha büyük olmalıdır.
  • Yer tutucu varlığı: Kullanıcı arayüzünün, görüntülenmeyen liste öğeleri için yer tutucular gösterip göstermeyeceğini belirler yükleme henüz tamamlanmadı. Google Etiket Yöneticisi'ni kullanmanın avantajları ve dezavantajları yer tutucular, kullanıcı arayüzü.

Sayfalandırma Kitaplığı'nın uygulamanızın veritabanını kullanarak, Executor LivePagedListBuilder, aşağıdaki kod snippet'inde gösterildiği gibidir:

KonserGörünümModeli

Kotlin

val myPagingConfig = Config(
        pageSize = 50,
        prefetchDistance = 150,
        enablePlaceholders = true
)

// The Int type argument corresponds to a PositionalDataSource object.
val myConcertDataSource : DataSource.Factory<Int, Concert> =
        concertDao.concertsByDate()

val concertList = myConcertDataSource.toLiveData(
        pagingConfig = myPagingConfig,
        fetchExecutor = myExecutor
)

Java

PagedList.Config myPagingConfig = new PagedList.Config.Builder()
        .setPageSize(50)
        .setPrefetchDistance(150)
        .setEnablePlaceholders(true)
        .build();

// The Integer type argument corresponds to a PositionalDataSource object.
DataSource.Factory<Integer, Concert> myConcertDataSource =
        concertDao.concertsByDate();

LiveData<PagedList<Concert>> concertList =
        new LivePagedListBuilder<>(myConcertDataSource, myPagingConfig)
            .setFetchExecutor(myExecutor)
            .build();

Doğru veri kaynağı türünü seçme

Kaynağınıza en uygun veri kaynağına bağlanmak önemlidir veri yapısı:

  • Tekliflerinizi otomatikleştirmek ve optimize etmek için Şu durumda PageKeyedDataSource: yüklediğiniz sayfalarda sonraki/önceki anahtarları kullanın. Örneğin, sosyal medya kurallarını ağdan medya yayınları yayınlıyorsanız bir kullanıcıdan nextPage jetonu fark edebilirsiniz.
  • Tekliflerinizi otomatikleştirmek ve optimize etmek için Şu durumda ItemKeyedDataSource: N+1 öğesini getirmek için N öğesindeki verileri kullanmanız gerekir. Örneğin, bir tartışma uygulaması için mesaj dizili yorumları getiriyorsanız ifadesini ekleyin.
  • Tekliflerinizi otomatikleştirmek ve optimize etmek için Şu durumda PositionalDataSource: veri sayfalarını veri mağazanızda seçtiğiniz herhangi bir konumdan getirmeniz gerekir. Bu sınıf, seçtiğiniz konuma bağlı olarak değişiyor. Örneğin, istek 50 veri öğesi döndürebilir. 1500 numaralı yerden başlayabilirsiniz.

Veriler geçersiz olduğunda bildir

Sayfalandırma Kitaplığı kullanılırken veri katmanına bir tablo veya satır eskidiğinde uygulamanızın diğer katmanları Bunun için şu numarayı arayın: invalidate() - Şu anda sahip olduğunuz DataSource sınıf seçmeniz gerekir.

Kendi veri kaynaklarınızı oluşturma

Özel bir yerel veri çözümü kullanıyorsanız veya verileri doğrudan ağda bulunan özelliklerden birini DataSource alt sınıfları. İlgili içeriği oluşturmak için kullanılan aşağıdaki kod snippet'i belirli bir konserin başlangıç zamanı:

Kotlin

class ConcertTimeDataSource() :
        ItemKeyedDataSource<Date, Concert>() {
    override fun getKey(item: Concert) = item.startTime

    override fun loadInitial(
            params: LoadInitialParams<Date>,
            callback: LoadInitialCallback<Concert>) {
        val items = fetchItems(params.requestedInitialKey,
                params.requestedLoadSize)
        callback.onResult(items)
    }

    override fun loadAfter(
            params: LoadParams<Date>,
            callback: LoadCallback<Concert>) {
        val items = fetchItemsAfter(
            date = params.key,
            limit = params.requestedLoadSize)
        callback.onResult(items)
    }
}

Java

public class ConcertTimeDataSource
        extends ItemKeyedDataSource<Date, Concert> {
    @NonNull
    @Override
    public Date getKey(@NonNull Concert item) {
        return item.getStartTime();
    }

    @Override
    public void loadInitial(@NonNull LoadInitialParams<Date> params,
            @NonNull LoadInitialCallback<Concert> callback) {
        List<Concert> items =
            fetchItems(params.key, params.requestedLoadSize);
        callback.onResult(items);
    }

    @Override
    public void loadAfter(@NonNull LoadParams<Date> params,
            @NonNull LoadCallback<Concert> callback) {
        List<Concert> items =
            fetchItemsAfter(params.key, params.requestedLoadSize);
        callback.onResult(items);
    }

Daha sonra, bu özelleştirilmiş verileri PagedList nesneleri içine yükleyebilirsiniz. somut alt sınıfı DataSource.Factory İlgili içeriği oluşturmak için kullanılan Aşağıdaki kod snippet'i, özel verilerin yeni örneklerinin nasıl oluşturulacağını gösterir önceki kod snippet'inde tanımlı kaynak:

Kotlin

class ConcertTimeDataSourceFactory :
        DataSource.Factory<Date, Concert>() {
    val sourceLiveData = MutableLiveData<ConcertTimeDataSource>()
    var latestSource: ConcertDataSource?
    override fun create(): DataSource<Date, Concert> {
        latestSource = ConcertTimeDataSource()
        sourceLiveData.postValue(latestSource)
        return latestSource
    }
}

Java

public class ConcertTimeDataSourceFactory
        extends DataSource.Factory<Date, Concert> {
    private MutableLiveData<ConcertTimeDataSource> sourceLiveData =
            new MutableLiveData<>();

    private ConcertDataSource latestSource;

    @Override
    public DataSource<Date, Concert> create() {
        latestSource = new ConcertTimeDataSource();
        sourceLiveData.postValue(latestSource);
        return latestSource;
    }
}

İçerik güncellemelerinin işleyiş şeklini düşünün

Gözlemlenebilir PagedList nesne; nasıl yapacağınızı düşünün nasıl çalıştığını da görebilirsiniz. Verileri doğrudan bir Odadan yüklüyorsanız veritabanı güncellemeleri uygulamanızın kullanıcı arayüzüne aktarılır otomatik olarak oluşturur.

Sayfalı ağ API'si kullanırken genellikle şunun gibi bir kullanıcı etkileşiminiz olur: "yenilemek için kaydırın", işlevini geçersiz kılmaya yönelik bir sinyal olarak En çok kullandığınız DataSource bakın. Ardından bu veri kaynağının yeni bir örneğini istiyorsunuz. Bu Kod snippet'i şu davranışı gösterir:

Kotlin

class ConcertActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        concertTimeViewModel.refreshState.observe(this, Observer {
            // Shows one possible way of triggering a refresh operation.
            swipeRefreshLayout.isRefreshing =
                    it == MyNetworkState.LOADING
        })
        swipeRefreshLayout.setOnRefreshListener {
            concertTimeViewModel.invalidateDataSource()
        }
    }
}

class ConcertTimeViewModel(firstConcertStartTime: Date) : ViewModel() {
    val dataSourceFactory = ConcertTimeDataSourceFactory(firstConcertStartTime)
    val concertList: LiveData<PagedList<Concert>> =
            dataSourceFactory.toLiveData(
                pageSize = 50,
                fetchExecutor = myExecutor
            )

    fun invalidateDataSource() =
            dataSourceFactory.sourceLiveData.value?.invalidate()
}

Java

public class ConcertActivity extends AppCompatActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        // ...
        viewModel.getRefreshState()
                .observe(this, new Observer<NetworkState>() {
            // Shows one possible way of triggering a refresh operation.
            @Override
            public void onChanged(@Nullable MyNetworkState networkState) {
                swipeRefreshLayout.isRefreshing =
                        networkState == MyNetworkState.LOADING;
            }
        };

        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshListener() {
            @Override
            public void onRefresh() {
                viewModel.invalidateDataSource();
            }
        });
    }
}

public class ConcertTimeViewModel extends ViewModel {
    private LiveData<PagedList<Concert>> concertList;
    private DataSource<Date, Concert> mostRecentDataSource;

    public ConcertTimeViewModel(Date firstConcertStartTime) {
        ConcertTimeDataSourceFactory dataSourceFactory =
                new ConcertTimeDataSourceFactory(firstConcertStartTime);
        mostRecentDataSource = dataSourceFactory.create();
        concertList = new LivePagedListBuilder<>(dataSourceFactory, 50)
                .setFetchExecutor(myExecutor)
                .build();
    }

    public void invalidateDataSource() {
        mostRecentDataSource.invalidate();
    }
}

Veri eşleştirme sağlayın

Sayfalama Kitaplığı, öğelerin öğeye ve sayfaya dayalı dönüştürmelerini destekler DataSource tarafından yüklenmiştir.

Aşağıdaki kod snippet'inde konser adı ile konser tarihi birleşimidir. şu adı ve tarihi içeren tek bir dizeyle eşlenir:

Kotlin

class ConcertViewModel : ViewModel() {
    val concertDescriptions : LiveData<PagedList<String>>
        init {
            val concerts = database.allConcertsFactory()
                    .map { "${it.name} - ${it.date}" }
                    .toLiveData(pageSize = 50)
        }
}

Java

public class ConcertViewModel extends ViewModel {
    private LiveData<PagedList<String>> concertDescriptions;

    public ConcertViewModel(MyDatabase database) {
        DataSource.Factory<Integer, Concert> factory =
                database.allConcertsFactory().map(concert ->
                    concert.getName() + "-" + concert.getDate());
        concertDescriptions = new LivePagedListBuilder<>(
            factory, /* page size */ 50).build();
    }
}

Bu özellik, satır açıldıktan sonra öğeleri sarmak, dönüştürmek veya hazırlamak istiyorsanız yararlı olabilir. yüklendi. Bu çalışma getirme yürütücü üzerinde yapıldığından, veya ayrı bir veritabanında sorgu yürütme gibi zorlu bir iş yüküne neden olabilir.

Geri bildirim gönder

Aşağıdaki kaynakları kullanarak geri bildiriminizi ve düşüncelerinizi bizimle paylaşın:

Sorun izleyici
Hataları düzeltebilmemiz için sorunları bildirin.

Ek kaynaklar

Sayfalandırma Kitaplığı hakkında daha fazla bilgi edinmek için şu sayfaya bakın: inceleyebilirsiniz.

Örnekler

Codelab'ler

Videolar

ziyaret edin. ziyaret edin.