Sayfa 2 kitaplığına genel bakış Android Jetpack'in bir parçasıdır.

Sayfalandırma Kitaplığı, tek seferde küçük veri parçalarını yüklemenize ve görüntülemenize yardımcı olur. İsteğe bağlı kısmi verilerin yüklenmesi, ağ bant genişliği ve sistem kullanımını azaltır kaynaklar.

Bu kılavuzda, kitaplıkla ilgili çeşitli kavramsal örnekler ve ve genel hatlarıyla inceleyelim. Bu kitaplığın, mobil kullanım için işlevlerini öğrenmek için codelab'i ve ek kaynaklar bölümüne bakın.

Kurulum

Sayfalama bileşenlerini Android uygulamanıza aktarmak için şunu ekleyin: uygulamanızın build.gradle dosyasına bağımlılıkları:

Eski

dependencies {
  def paging_version = "2.1.2"

  implementation "androidx.paging:paging-runtime:$paging_version" // For Kotlin use paging-runtime-ktx

  // alternatively - without Android dependencies for testing
  testImplementation "androidx.paging:paging-common:$paging_version" // For Kotlin use paging-common-ktx

  // optional - RxJava support
  implementation "androidx.paging:paging-rxjava2:$paging_version" // For Kotlin use paging-rxjava2-ktx
}

Kotlin

dependencies {
  val paging_version = "2.1.2"

  implementation("androidx.paging:paging-runtime:$paging_version") // For Kotlin use paging-runtime-ktx

  // alternatively - without Android dependencies for testing
  testImplementation("androidx.paging:paging-common:$paging_version") // For Kotlin use paging-common-ktx

  // optional - RxJava support
  implementation("androidx.paging:paging-rxjava2:$paging_version") // For Kotlin use paging-rxjava2-ktx
}

Kütüphane mimarisi

Bu bölümde, sayfa oluşturma kitaplığının ana bileşenleri açıklanır ve gösterilir.

Sayfalı Liste

Sayfalandırma Kitaplığı'nın temel bileşeni, PagedList sınıfı (yüklenen) veya sayfalardan oluşur. Daha fazla veri gerektiği için sayfa numarası mevcut PagedList nesnesine eklendi. Yüklenen verilerden herhangi biri değişirse, yeni bir PagedList örneği, gözlemlenebilir veri sahibine LiveData veya RxJava2 tabanlı nesne. Farklı PagedList nesne oluşturuldu, Uygulamanızın kullanıcı arayüzü, içeriklerini gösterirken kullanıcı arayüzü denetleyicilerinize saygı gösterir yaşam döngülerini takip edin.

Aşağıdaki kod snippet'i, uygulamanızın görünüm modelini PagedList nesnelerin LiveData tutucusunu kullanarak verileri yükleyip sunun:

Kotlin

class ConcertViewModel(concertDao: ConcertDao) : ViewModel() {
    val concertList: LiveData<PagedList<Concert>> =
            concertDao.concertsByDate().toLiveData(pageSize = 50)
}

Java

public class ConcertViewModel extends ViewModel {
    private ConcertDao concertDao;
    public final LiveData<PagedList<Concert>> concertList;

    // Creates a PagedList object with 50 items per page.
    public ConcertViewModel(ConcertDao concertDao) {
        this.concertDao = concertDao;
        concertList = new LivePagedListBuilder<>(
                concertDao.concertsByDate(), 50).build();
    }
}

Veri

Her bir PagedList örneği yüklenir İlgili uygulamadan uygulamanızın verilerinin güncel bir anlık görüntüsü DataSource nesne olarak tanımlar. Veri akışları "PagedList" nesnesine aktarmanızı sağlar.

Aşağıdaki örnekte Oda kalıcılığı kullanılmaktadır. kitaplığını değiştirebilirsiniz, ancak verilerinizi başka bir şekilde depolamak istiyorsanız, kendi verilerinizi de bilgi sağlar.

Kotlin

@Dao
interface ConcertDao {
    // The Int type parameter tells Room to use a PositionalDataSource object.
    @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.
    @Query("SELECT * FROM concerts ORDER BY date DESC")
    DataSource.Factory<Integer, Concert> concertsByDate();
}

PagedList nesnesine nasıl veri yükleyebileceğiniz hakkında daha fazla bilgi edinmek için Sayfalandırılmış verileri yükleme rehberini inceleyin.

Kullanıcı Arayüzü

PagedList sınıfı bir PagedListAdapter ve öğeleri bir RecyclerView. Bu sınıfların birlikte çalışarak içeriği getirmesi ve görüntülemesi, önceden getirme işlemini görünüm dışı içerik ve içerik değişikliklerinin canlandırması.

Daha fazla bilgi edinmek için Sayfa sayfası görüntüleme listeler.

Farklı veri mimarilerini destekleme

Sayfalandırma Kitaplığı aşağıdaki veri mimarilerini destekler:

  • Yalnızca arka uç sunucusundan sunulur.
  • Yalnızca cihaz üzerindeki bir veritabanında depolanır.
  • Diğer kaynakların bir kombinasyonu (cihazdaki veritabanını önbellek olarak kullanır).

Şekil 1'de bu mimari senaryolarının her birinde veri akışı gösterilmektedir. İçinde yalnızca ağ ya da yalnızca veritabanı içeren bir çözümde veriler doğrudan uygulamanızın kullanıcı arayüzü modeli. Birleşik bir yaklaşım kullanıyorsanız veriler cihaz üzerindeki bir veritabanına ve ardından uygulamanızın kullanıcı arayüzü modeline bağlamanız gerekir. Bazen, her veri akışının uç noktasında yüklenecek veriler biter. Bu noktada, verileri sağlayan bileşenden daha fazla veri ister. Örneğin, cihaz üzerindeki veri tabanında veri kalmadığında daha fazla veri sunucudan kaldıracak.

Veri akışı diyagramları
Şekil 1. Verinin, farklı mimarilerde nasıl aktığı Sayfalama Kitaplığı desteği
ziyaret edin.

Bu bölümün sonraki bölümlerinde, her bir bileşenin yapılandırmasıyla ilgili veri akışı kullanım alanı.

Yalnızca ağ

Bir arka uç sunucusundan veri görüntülemek için şunun eşzamanlı sürümünü kullanın: Yüklenecek Retrofit API bilgileri kendi özel DataSource alanınıza sığdırın nesne.

Yalnızca veritabanı

RecyclerView cihazınızı ayarlayın tercihen Oda kalıcılığını kullanarak yerel depolama alanını kitaplığı. Böylece veriler ne zaman veritabanına eklendiğinde veya değiştirildiğinde, bu değişiklikler otomatik RecyclerView içine yansıtılacaktır.

Ağ ve veritabanı

Veritabanını incelemeye başladıktan sonra, veri tabanındaki verilerin tükenmesi durumunda, PagedList.BoundaryCallback. Ardından, ağınızdan daha fazla öğe getirebilir ve bunları Kullanıcı arayüzünüz veritabanını gözlemliyorsa tek yapmanız gereken budur.

Ağ hatalarını işleme

Gösterdiğiniz verileri getirmek veya sayfalandırmak için için, ağın "müsait" veya "kullanılamıyor" bağlantı her zaman kesildiğinden ya da gevşek olmalıdır:

  • Belirli bir sunucu ağ isteğine yanıt veremeyebilir.
  • Cihaz yavaş veya zayıf bir ağa bağlı olabilir.

Bunun yerine, uygulamanız her isteği hata kontrolüyle kontrol etmeli ve ve uygun bir çözüm bulmanız gerekir. Örneğin, "yeniden deneyin" kullanıcıların veri yenileme adımında seçebileceği düğme. çalışmaz. Veri sayfalama adımında hata oluşursa en iyisi yeniden denemektir otomatik olarak oluşturulur.

Mevcut uygulamanızı güncelleyin

Uygulamanız zaten bir veritabanından veya arka uç kaynağından veri kullanıyorsa doğrudan Sayfalandırma Kitaplığı'nın sağladığı işlevlere yükseltme olanağı sunar. Bu bölümde, mevcut ortak bir tasarıma sahip bir uygulamanın nasıl yeni sürüme geçirileceği gösterilmektedir.

Özel sayfalama çözümleri

Uygulamanızın web sitesindeki verilerin küçük alt kümelerini yüklemek için bu mantığı önceki veri kaynağındaki PagedList sınıfı. Örnekler PagedList, yaygın veri kaynaklarıyla yerleşik bağlantılar sunar. Bu örnekler adaptörler de sağlar. RecyclerView nesne pek çok değişiklik yapabilirsiniz.

Veriler, sayfalar yerine listeler kullanılarak yüklendi

Kullanıcı arayüzünüz için yedekleme veri yapısı olarak bellek içi liste kullanıyorsanız adaptörü kullanarak veri güncellemelerini Numaraysa PagedList sınıfı öğe büyüyebilir. PagedList örnekleri şunlardan birini kullanabilir LiveData<PagedList> veya Veri güncellemelerini uygulamanızın kullanıcı arayüzüne aktararak yükleme sürelerini en aza indirmek için Observable<List> ve bellek kullanımı. Daha da iyisi, bir List PagedList nesnesi bulunan bir nesne için cihazınızda herhangi bir değişiklik uygulamanın kullanıcı arayüzü yapısı veya veri güncelleme mantığı.

CursorAdapter'ı kullanarak bir veri imlecini liste görünümüyle ilişkilendirme

Uygulamanız CursorAdapter kullanabilir kullanarak bir Cursor üzerindeki verileri bir ListView. Bu durumda genellikle ListView uygulamasından bir RecyclerView: uygulamanızın liste kullanıcı arayüzü kapsayıcısını açın, ardından Cursor öğesini değiştirin bileşenini Oda veya PositionalDataSource (Cursor örneklerinin bir SQLite veritabanı.

Bazı durumlarda, örneğin projenizde Spinner ise yalnızca bağdaştırıcıyı sağlarsınız kendisi. Ardından bir kitaplık, bu bağdaştırıcıya yüklenen verileri alır ve sizin için verileri görüntüler. Böyle durumlarda, erişim için bağdaştırıcının verilerini LiveData<PagedList>, ardından sarmala bu listeyi ArrayAdapter nesnesinde bulabilirsiniz .

AsyncListUtil kullanarak içeriği eşzamansız olarak yükleme

Şunu kullanıyorsanız: AsyncListUtil nesne bilgi gruplarını eşzamansız olarak yükleyip görüntülediğinizde, Sayfalandırma Kitaplığı Böylece verileri daha kolay yükleyebilirsiniz:

  • Verilerinizin konumsal olması gerekmez. Sayfalandırma Kitaplığı, Bu veriler, ağın sağladığı anahtarları kullanarak doğrudan arka ucunuzdan alınır.
  • Verileriniz sayılamayacak kadar büyük olabilir. Sayfa Oluşturma Kitaplığı'nı kullanarak kalan veri kalmayana kadar verileri sayfalara aktarmanızı öneririz.
  • Verilerinizi daha kolay bir şekilde gözlemleyebilirsiniz. Sayfalama kitaplığı, uygulamanızın ViewModel'inin gözlemlenebilir bir veri yapısında sakladığı verilerdir.
ziyaret edin.

Veritabanı örnekleri

Aşağıdaki kod snippet'leri, tüm parçalara sahip olmanın olası yollarını göstermektedir. yardımcı olabilir.

LiveData kullanarak sayfalandırılmış verileri gözlemleme

Aşağıdaki kod snippet'i birlikte çalışan tüm parçaları gösterir. Konser şeklinde veya veritabanında etkinlik eklendiğinde, kaldırıldığında veya değiştirildiğinde, RecyclerView otomatik ve verimli bir şekilde güncellenir:

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

class ConcertViewModel(concertDao: ConcertDao) : ViewModel() {
    val concertList: LiveData<PagedList<Concert>> =
            concertDao.concertsByDate().toLiveData(pageSize = 50)
}

class ConcertActivity : AppCompatActivity() {
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Use the 'by viewModels()' Kotlin property delegate
        // from the activity-ktx artifact
        val viewModel: ConcertViewModel by viewModels()
        val recyclerView = findViewById(R.id.concert_list)
        val adapter = ConcertAdapter()
        viewModel.concertList.observe(this, PagedList(adapter::submitList))
        recyclerView.setAdapter(adapter)
    }
}

class ConcertAdapter() :
        PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
    fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
        val concert: Concert? = getItem(position)

        // Note that "concert" is a placeholder if it's null.
        holder.bindTo(concert)
    }

    companion object {
        private val DIFF_CALLBACK = object :
                DiffUtil.ItemCallback<Concert>() {
            // Concert details may have changed if reloaded from the database,
            // but ID is fixed.
            override fun areItemsTheSame(oldConcert: Concert,
                    newConcert: Concert) = oldConcert.id == newConcert.id

            override fun areContentsTheSame(oldConcert: Concert,
                    newConcert: Concert) = oldConcert == newConcert
        }
    }
}

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

public class ConcertViewModel extends ViewModel {
    private ConcertDao concertDao;
    public final LiveData<PagedList<Concert>> concertList;

    public ConcertViewModel(ConcertDao concertDao) {
        this.concertDao = concertDao;
        concertList = new LivePagedListBuilder<>(
            concertDao.concertsByDate(), /* page size */ 50).build();
    }
}

public class ConcertActivity extends AppCompatActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ConcertViewModel viewModel =
                new ViewModelProvider(this).get(ConcertViewModel.class);
        RecyclerView recyclerView = findViewById(R.id.concert_list);
        ConcertAdapter adapter = new ConcertAdapter();
        viewModel.concertList.observe(this, adapter::submitList);
        recyclerView.setAdapter(adapter);
    }
}

public class ConcertAdapter
        extends PagedListAdapter<Concert, ConcertViewHolder> {
    protected ConcertAdapter() {
        super(DIFF_CALLBACK);
    }

    @Override
    public void onBindViewHolder(@NonNull ConcertViewHolder holder,
            int position) {
        Concert concert = getItem(position);
        if (concert != null) {
            holder.bindTo(concert);
        } else {
            // Null defines a placeholder item - PagedListAdapter automatically
            // invalidates this row when the actual object is loaded from the
            // database.
            holder.clear();
        }
    }

    private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK =
            new DiffUtil.ItemCallback<Concert>() {
        // Concert details may have changed if reloaded from the database,
        // but ID is fixed.
        @Override
        public boolean areItemsTheSame(Concert oldConcert, Concert newConcert) {
            return oldConcert.getId() == newConcert.getId();
        }

        @Override
        public boolean areContentsTheSame(Concert oldConcert,
                Concert newConcert) {
            return oldConcert.equals(newConcert);
        }
    };
}

RxJava2 kullanarak sayfalandırılmış verileri gözlemleme

Örneğin, RxJava2 yerine LiveData yerine şunu yapabilirsiniz: Observable veya Flowable nesnesi oluşturun:

Kotlin

class ConcertViewModel(concertDao: ConcertDao) : ViewModel() {
    val concertList: Observable<PagedList<Concert>> =
            concertDao.concertsByDate().toObservable(pageSize = 50)
}

Java

public class ConcertViewModel extends ViewModel {
    private ConcertDao concertDao;
    public final Observable<PagedList<Concert>> concertList;

    public ConcertViewModel(ConcertDao concertDao) {
        this.concertDao = concertDao;

        concertList = new RxPagedListBuilder<>(
                concertDao.concertsByDate(), /* page size */ 50)
                        .buildObservable();
    }
}

Daha sonra aşağıdaki kodu kullanarak verileri gözlemlemeye başlayabilir ve bunu durdurabilirsiniz: snippet:

Kotlin

class ConcertActivity : AppCompatActivity() {
    private val adapter = ConcertAdapter()

    // Use the 'by viewModels()' Kotlin property delegate
    // from the activity-ktx artifact
    private val viewModel: ConcertViewModel by viewModels()

    private val disposable = CompositeDisposable()

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val recyclerView = findViewById(R.id.concert_list)
        recyclerView.setAdapter(adapter)
    }

    override fun onStart() {
        super.onStart()
        disposable.add(viewModel.concertList
                .subscribe(adapter::submitList)))
    }

    override fun onStop() {
        super.onStop()
        disposable.clear()
    }
}

Java

public class ConcertActivity extends AppCompatActivity {
    private ConcertAdapter adapter = new ConcertAdapter();
    private ConcertViewModel viewModel;

    private CompositeDisposable disposable = new CompositeDisposable();

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        RecyclerView recyclerView = findViewById(R.id.concert_list);

        viewModel = new ViewModelProvider(this).get(ConcertViewModel.class);
        recyclerView.setAdapter(adapter);
    }

    @Override
    protected void onStart() {
        super.onStart();
        disposable.add(viewModel.concertList
                .subscribe(adapter.submitList(flowableList)
        ));
    }

    @Override
    protected void onStop() {
        super.onStop();
        disposable.clear();
    }
}

ConcertDao ve ConcertAdapter için aynı kod RxJava2 tabanlı çünkü daha önce LiveData tabanlı bir çözümdür.

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.