LoginSignup
7

posted at

updated at

Organization

JetpackComposeでカレンダーを作れるライブラリ

個人開発でカレンダーを作りたくていい感じの方法を探していた時に見つけた
良さげなライブラリの紹介です。

Calendar

知らなかったんですが結構使われてるみたいで、
大分好きに見た目など変えられるみたいで良さそうだし
サンプルのカレンダーが豊富🤔

カレンダーを作っていく方法

ライブラリの導入

build.gradleにこちらを追加

dependencies {
  // Compose用
  implementation 'com.kizitonwose.calendar:compose:<latest-version>'
}

カレンダーの作成

ここにCompose向けの利用法がまとまっている

カレンダーの描画に必要になるものなどと、
カレンダーを描画するライブラリ内のComposable関数の呼び出し部分をドキュメント参考に書いていったのが下記

@Composable
fun CalendarDisplay() {
    // 現在の年月
    val currentMonth = remember { YearMonth.now() }
    // 現在より前の年月
    val startMonth = remember { currentMonth.minusMonths(100) }
    // 現在より後の年月
    val endMonth = remember { currentMonth.plusMonths(100) }
    // 曜日
    val daysOfWeek = remember { daysOfWeek() }
    // カレンダーの状態を持つ
    val state = rememberCalendarState(
        startMonth = startMonth,
        endMonth = endMonth,
        firstVisibleMonth = currentMonth,
        firstDayOfWeek = daysOfWeek.first(),
        outDateStyle = OutDateStyle.EndOfGrid
    )

    // 横スクロールのカレンダーを作成するためのComposable関数
    // 縦スクロールのVerticalなどもある
    HorizontalCalendar(
        state = state,
        // 日付を表示する部分
        dayContent = {Day(it)},
        // カレンダーのヘッダー
        monthHeader = {DaysOfWeekTitle(daysOfWeek = daysOfWeek)}
    )
}

ヘッダー

曜日の表示を行うComposable関数を作成している

@Composable
fun DaysOfWeekTitle(daysOfWeek: List<DayOfWeek>) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
    ) {
        for ((index, dayOfWeek) in daysOfWeek.withIndex()) {
            Text(
                modifier = Modifier.weight(1f),
                textAlign = TextAlign.Center,
                text = dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.getDefault()),
                // 土日だけそれぞれ色を変えたいので対応したカラーコードを返している
                color = getDayOfWeekTextColor(index)
            )
        }
    }
}

日付表示部分

カレンダーの日付にあたる部分を表示するためのComposable関数を作成する。
日付をタップした時の挙動や、月始まりと終わりの前後にある前月や次の月の日付をグレーアウトさせるなどはこの中でやるのがいいっぽい。

@Composable
fun Day(day: CalendarDay) {
    Box(
        modifier = Modifier
            .aspectRatio(1f),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = day.date.dayOfMonth.toString(),
            // ここで今月でないものの日付をグレーアウトさせている
            color = if (day.position == DayPosition.MonthDate) Color.Black else Color.Gray
        )
    }
}

実際に作成した画面

個人開発の方で実際に上記のコードをもとに色々追加で書いて作成した画面がこんな感じ。
比較的簡単に実装でき、見た目もいじりやすく作成者様には感謝です。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
7