Realays Logo Realays
← Back to Blog
DevLog 2025/12/17

[Dalendar DevLog 7] カレンダーアプリの核心構造: ネストされたRecyclerViewで月間ビューを作る

月単位スクロールと日付グリッドを効率的に実装するために二重RecyclerView構造を採択した背景と詳細実装内容を紹介します。

[Dalendar DevLog 7] カレンダーアプリの核心構造: ネストされたRecyclerViewで月間ビューを作る

7編: カレンダーアプリの核心構造: ネストされたRecyclerViewで月間ビューを作る

1. 始めに: スクロール可能な月間カレンダーの目標設定

今回の文章では私が基本的な形態のカレンダーアプリをどのように実装したのか共有してみようと思います。核心要求事項は「一画面に一ヶ月ずつ表示」して、「左右スクロールを通じて移動」することでした。

2. 核心アーキテクチャ: 二重RecyclerView構造

私が実装したアプリの基本構造は2つのRecyclerViewをネストさせることです。参考コードの核心でもあるこの構造を通じて月単位の左右スクロールと月別日付グリッド表示を効率的に処理できました。

  1. メイン画面 (MainActivity): アプリが初めて実行されるとき現れる画面です。
  2. 月(Month)のためのRecyclerView (A): このRecyclerViewは各アイテムが一ヶ月全体を表します。左右にスクロールして月をめくることができます。
  3. 日(Day)のためのRecyclerView (B): このRecyclerViewはAの各アイテム内部にネストされた形態で存在します。6行7列のグリッド(Grid)レイアウトを持ち、計42個のアイテムがそれぞれ一日を表す方式です。

RecyclerViewは枠(viewholder)を再活用してシステム資源を効率的に使用します。レイアウトマネージャーを通じて再活用方式を自由に設定できるのが大きな長所です。

3. 実装詳細: 月(月)生成ロジック (RecyclerView A)

3.1. 「無限」スクロールのための初期位置設定

ユーザーが過去と未来、双方向にずっとスクロールできるように見せるために、私は月RecyclerView(A)の初期位置を非常に大きな値に設定しました。

// MainActivity.kt
scrollToPosition(Int.MAX_VALUE/2)

Int.MAX_VALUEの半分を開始位置に設定することで、ユーザーが左(過去)や右(未来)へスクロールするとき事実上果てしなく移動するかのような「無限スクロール」効果を実装できます。

3.2. スクロールによる月計算

実際の月(月)を計算するロジックは現在のpositionを基準にします。

calendar.add(Calendar.MONTH, position - center)

現在アイテムのpositionと中央位置(center)の差を計算して月を調整します。これのおかげで左右スクロールを通じて月が自然に変更されます。

4. 実装詳細: 日(日)生成ロジック (RecyclerView B)

各月に該当する6x7グリッド(計42個セル)の日付を生成するロジックは月RecyclerView(A)で計算された特定月を基準に行われます。

  1. リスト初期化: 42個の日付オブジェクトを入れるリストを生成します。
  2. 日付生成ループ: 該当月の1日が含まれた週の日曜日から始めて42個の日付を順次生成します。
  3. データ伝達: 日付がすべて埋まったdayListは最終的に日RecyclerView(B)を担当するアダプターに伝達されて画面に表示されます。

5. 仕上げ

参考コードを私のプロジェクトに合わせて適用しながらビューバインディング(view binding)を使用するようにコードを修正する小さな作業が必要でした。こうしてネストされたRecyclerViewを活用して月単位スクロールが可能なカレンダーの基本骨格を成功裏に完成させることができました。

関連記事