SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

BizReach Tech Blog

Android 8.0とAndroid Studio 3.0で始めるReactive Extensionsを用いたアプリ開発

BizReach Tech Blog 第2回


データ更新処理

 一般的に、RecyclerViewを使った画面のデータ更新処理は「初回画面表示した時に更新」「画面上部から引っ張って更新」と「一番下までスクロールしたら次のページを読み込む」の3つが考えられます。

 先の2つは特に迷うことなくFragment#onResume()やSwipeRefreshLayout#setOnRefreshListener()でデータロード処理を呼び出すと良いでしょう。

 3つ目の一番下までスクロールしたら次のページを読み込む処理については、RxJava+RxBinding (recyclerview-v7)ライブラリを利用すれば安全かつシンプルに実装できます。以下のコードに示す通り、データロード中に画面下部到達イベントを発生させない、イベントを重複して発生させないといった制約を課すことができます。

public class UserListFragment extends Fragment {
    ...
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ...
        
        bindEvents();
    }
    
    ...
    
    /**
     * イベントハンドラーを登録します。
     */
    private void bindEvents() {
        ...
        
        // RecyclerViewのスクロールイベント
        RxRecyclerView.scrollEvents(mRecyclerView)
                // ロード完了までは無視する
                .skipUntil(mDataLoadedNotification)
                // 最下部に達したら
                .filter(REACH_BOTTOM)
                // 一回だけ通知
                .take(1)
                // 通知が完了したら、またListenする
                .repeat()
                // 通知が開始されたら、プログレスダイアログ表示
                .doOnNext(e -> ProgressDialogFragment.show(getFragmentManager()))
                // ハンドラーを設定
                .subscribe(this::onReachBottom);
    }
    
    ...
    
    /**
     * リストの最下部到達イベントをハンドリングします。
     *
     * @param ignore {@link RecyclerViewScrollEvent}
     */
    private void onReachBottom(final RecyclerViewScrollEvent ignore) {
        loadUserList();
    }
}

 上記のコードで利用しているREACH_BOTTOMは、RecyclerViewScrollEventに対して最下部に達しているかどうかをチェックする述語(Predicateインターフェースの実装)です。RxBindingを使っていない場合であれば、RecyclerView.OnScrollListenerの実装クラスで似たような実装をしていると思います。

/**
 * RecyclerViewのスクロールが最下部に達していることを判定する{@link Predicate}
 */
private static final Predicate<RecyclerViewScrollEvent> REACH_BOTTOM = e -> Optional.of(e)
        // viewを取得
        .map(RecyclerViewScrollEvent::view)
        // レイアウトマネージャーを取得
        .map(RecyclerView::getLayoutManager)
        // LinearLayoutManagerへキャスト
        .map(LinearLayoutManager.class::cast)
        // 要素が1つ以上あるか?
        .filter(lm -> lm.getItemCount() > 0)
        // 最後の要素が見えているか?
        .map(lm -> {
            // 最終要素のインデックス
            final int last = lm.getItemCount() - 1;
            // 今見えている最終要素のインデックス
            final int curr = lm.findLastCompletelyVisibleItemPosition();
            
            return last <= curr;
        }).orElse(false);

 ここで利用したRxBinding (recylerview-v7)ライブラリは、build.gradleを以下のように設定する必要があります。こちらもProGuard設定は不要です。

dependencies {
    ...略...
    
    compile 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'
    
    ...略...
}

最後に

 Android 8.0、Android Studio 3.0とReactive Extensions(RxJava2)を中心として、有用なライブラリを用いたAndroidアプリ開発について、チャットアプリケーションを題材として解説しました。特にdesugarによるJava 8ビルド環境は、RetroLambdaを利用する場合の問題点(メソッド数の増加、Java 8コードを含むサードパーティライブラリは利用不可)を解決します。Jackがサポート終了になってしまったことも考慮すれば、しばらくデファクトスタンダードとして君臨するのではないでしょうか。この機会にRetroLambdaやJackから移行してみてはいかがでしょう。

 また、RxJavaが開くReactive Extensionsの世界はAndroidアプリの開発においても有用なものが多くあります、RxをイベントのPub/Sub機構として捉えた場合、イベントそのものを途中で加工したり、イベントの流量を制御したりといったことが簡単に実装できるのが最も有用な点ではないでしょうか。

 なお、添付のソースコードでは記事には書き切れなかった下記の実装も含んでいます。何かの参考になれば幸いです。

  • Fragment間遷移でShared Elements Transition
  • AndroidKeyStoreを使ったローカルへの暗号化データ保存
  • XML上で調整可能な設定項目を有するカスタムView

developer.android.comのコンテンツ利用に伴う表記

 Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
BizReach Tech Blog連載記事一覧

もっと読む

この記事の著者

岩井 友希(株式会社ビズリーチ)(イワイ トモキ)

SIer、フリーランスを経て、2015年にビズリーチへ入社。 Java、Python、Android、iOS、Linuxたまにセキュリティとかのキーワードに反応するエンジニアです。 github:https://github.com/TomokiIwai 株式会社ビズリーチについて:https://www.bizreach.co.jp/recruit/

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10676 2018/10/17 15:47

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー