Javaでのページングライブラリの利用
一通りRoom+ページングライブラリをKotlinでコーディングする方法を紹介したところで、Javaでのコーディングに話を移しましょう。なお、PhoneDAOインターフェース、Phoneエンティティクラス、リポジトリクラスともに、KotlinコードをJavaコードに置き換えただけのコードなので割愛します。
JavaではLiveDataを利用
一番大きな違いは、JavaではFlowの代わりにLiveDataを利用する点です。そのため、Kotlinでは、Flowを抽出していたViewModel内のコードが変わってきます。これは、リスト9のコードとなります。
public class MainViewModel extends AndroidViewModel { private static final int ITEMS_PER_PAGE = 50; // (1) private PhoneRepository _phoneRepository; private LiveData<PagingData<Phone>> _phoneListLiveData; // (2) public MainViewModel(@NonNull Application application) { super(application); _phoneRepository = new PhoneRepository(application); PagingSource<Integer, Phone> phoneListPageSource = _phoneRepository.getAllPhoneListPagingSource(); // (3) PagingConfig pagingConfig = new PagingConfig(ITEMS_PER_PAGE); // (4) Pager<Integer, Phone> phoneListPager = new Pager<>(pagingConfig, () -> phoneListPageSource); // (5) CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(MainViewModel.this); // (7) _phoneListLiveData = PagingLiveData.cachedIn(PagingLiveData.getLiveData(phoneListPager), viewModelScope); // (8) } public LiveData<PagingData<Phone>> getPhoneListLiveData() { return _phoneListLiveData; } }
リスト9の(1)(3)(4)(5)は、リスト5のそれぞれに対応するKotlinコードをJavaコードに置き換えただけのコードとなっています。一番の違いは(2)のフィールドの型がLiveDataとなっていることです。JavaではFlowが使えないため、当然です。それに伴い、このLiveDataを抽出するコードも(8)のように変わります。もともとKotlin用に作られたページングライブラリなので、内部のFlowオブジェクトをLiveDataに変換するクラスとしてPagingLiveDataが別に用意されています。そのstaticメソッドであるgetLiveData()を利用し、LiveDataを抽出します。さらに、同じくcachedIn()メソッドを利用して、抽出したLiveDataに対して、リスト5の(6)で行ったcachedIn()メソッドと同様の効果を施します。
getLiveData()メソッドは、引数としてPagerオブジェクトを渡すので、(8)では(5)で生成したphoneListPagerを渡しています。そのようにして抽出したLiveDataをcachedIn()の第1引数とします。一方、cachedIn()の第2引数は、コルーチンスコープを渡すことになっています。Javaには、このコルーチンスコープという概念がないので、これもKotlin由来の専用クラスであるViewModelKtのstaticメソッド、getViewModelScope()メソッドを利用して取得します。それが(7)のコードです。
オブザーバの用意
Javaでは、ページデータがFlowではなくLiveDataとなることで、アクティビティやフラグメントでのRecyclerViewとの連携もコードも変わってきます。
まず、アダプタクラスであるPhoneListAdapterやDiffUtil.ItemCallbackクラスであるPhoneComparatorは、KotlinコードをそのままJavaコードに変換したものとなるので、割愛します。一方、アダプタクラスのsubmitData()の実行コードが変わってきます。これはリスト10のように、オブザーバクラス内となります。
@Override protected void onCreate(Bundle savedInstanceState) { : LiveData<PagingData<Phone>> phoneListLiveData = _mainViewModel.getPhoneListLiveData(); phoneListLiveData.observe(MainActivity.this, new PhoneListObserver()); // (1) } private class PhoneListObserver implements Observer<PagingData<Phone>> { // (2) @Override public void onChanged(<PagingData<Phone>> phonePagingData) { _phoneListAdapter.submitData(getLifecycle(), phonePagingData); // (3) } }
リスト10の(1)のように、ViewModelから取得したLiveDataに対してオブザーバを登録します。そのオブザーバクラスが(2)のPhoneListObserverであり、そのメソッドonChanged()内でアダプタのsubmitData()を実行します。ただし、Kotlinコードとは違い、(3)のように、引数が2個必要です。順番は前後しますが、第2引数は、KotlinコードでのsubmitData()の実行同様に、新しいデータです。したがって、onChanged()の引数をそのまま渡します。一方、第1引数がKotlinコードにはなく、ライフサイクルを渡す必要があります。これは、getLifecycle()メソッドの戻り値を渡します。
まとめ
Android Jetpackについて紹介していく本連載の第12回は、いかがでしたでしょうか。
今回は、ページングライブラリの基礎的な使い方を紹介しました。次回は、ページングライブラリをもう少し掘り下げ、PagingSourceクラスの自作方法やネット上のデータとRoomを連携させてページングする方法を紹介します。