Genta Hirauchi

公開日:2020/02/18
更新日:2020/03/22

【Kotlin基礎】CalendarViewでカレンダーを実装する方法を解説

  • Kotlinでカレンダーを表示する方法が知りたい。
  • CalendarViewをコードで動的に実装したい。
  • 日付が選択された時に、何らかの処理を行いたい。

アプリを開発するなかで、「カレンダーが表示できたらなぁ」と思ったことはありませんか?

Kotlinには、CalendarViewというお手軽にカレンダーを表示することができるViewが存在します。

本記事では、そんなCalendarViewの基本的な実装方法や、ユーザーが日付を選択した際のイベントを受け取る方法などを、サンプルコードを交え、わかりやすく解説しております。

目次

CalendarViewでカレンダーを実装する方法

Kotlinでカレンダーを実装するには、CalendarViewというViewを使用します。

【公式ドキュメント】 : CalendarView | Android Developers

CalendarViewを実装するには、xmlで実装する方法と、コードで動的に実装する方法の、2通りの方法があります。

xmlでCalendarViewを実装する

まずは、xmlで実装する方法を紹介致します。xmlで実装するには、以下のように実装します。
※ 記事作成日は、2020年2月18日(火)です。

【xmlで実装】

  • MainActivity.kt
  • activity_main.xml
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   tools:context=".MainActivity"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical">

   <CalendarView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

</LinearLayout>

CalendarViewを実装するには、<CalendarView/>タグを使用します。

Point
  • xmlでカレンダーを実装するには、<CalendarView/>タグを使用する

コードで動的にCalendarViewを実装する

続いて、コードで動的に実装する方法を紹介致します。コードで動的に実装するには、以下のように実装します。

【コードで実装】

  • MainActivity.kt
  • activity_main.xml
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   // CalendarViewの生成
   val calendarView = CalendarView(this)
   calendarView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)

   // 親レイアウトに、CalendarViewを追加
   val linearLayout = findViewById<LinearLayout>(R.id.container)
   linearLayout.addView(calendarView)
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   tools:context=".MainActivity"
   android:id="@+id/container"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
</LinearLayout>

CalendarView()で、CalendarViewのインスタンスを生成しております。

その後、親レイアウトのlinearLayoutに対し、addView()でCalendarViewを追加しております。

Point
  • コードで実装するには、CalendarView()でインスタンスを生成した後、addView()で追加する

CalendarViewの基本的な使い方

選択日を設定・取得する方法

続いて、カレンダーの選択日を設定・取得する方法を紹介致します。

以下は、カレンダーの選択日を2日後に変更するサンプルコードです。

  • MainActivity.kt
  • activity_main.xml
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val format = SimpleDateFormat("yyyy/MM/dd", Locale.US)

   val calendarView = findViewById<CalendarView>(R.id.calendar)

   // 初期選択日を取得
   val defaultDate = calendarView.date
   println(format.format(defaultDate))

   // 2日後の日付を取得
   val calendar = Calendar.getInstance()
   calendar.add(Calendar.DATE, 2)

   // 選択日を2日後に変更
   calendarView.date = calendar.timeInMillis

   // 変更後の選択日を取得
   val newDate = calendarView.date
   println(format.format(newDate))
}

[出力結果]
2020/02/18
2020/02/20
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   tools:context=".MainActivity"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <CalendarView
       android:id="@+id/calendar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</LinearLayout>

CalendarViewの選択日を設定・取得するには、dateを使用します。

dateで設定・取得する値は、UNIX時間のミリ秒です。サンプルコードでは、SimpleDateFormatで年月日に変更して出力しております。

Point
  • CalendarViewの選択日を設定・取得するには、dateを使用する

選択可能日を設定・取得する方法

続いて、カレンダーの選択可能日を設定・取得する方法を紹介致します。

以下は、カレンダーの過去の選択可能日を5日前に、未来の選択可能日を1ヶ月後に変更するサンプルコードです。

  • MainActivity.kt
  • activity_main.xml
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val format = SimpleDateFormat("yyyy/MM/dd", Locale.US)

   val calendarView = findViewById<CalendarView>(R.id.calendar)

   // 初期の過去の選択可能日を取得
   val defaultMinDate = calendarView.minDate
   println("初期の過去の選択可能日:" + format.format(defaultMinDate))

   // 初期の未来の選択可能日を取得
   val defaultMaxDate = calendarView.maxDate
   println("初期の未来の選択可能日:" + format.format(defaultMaxDate))

   // 5日前の日付を取得
   var calendar = Calendar.getInstance()
   calendar.add(Calendar.DATE, -5)

   // 過去の選択可能日を5日前に変更
   calendarView.minDate = calendar.timeInMillis

   calendar = Calendar.getInstance()
   calendar.add(Calendar.MONTH, 1)

   // 未来の選択可能日を1ヶ月後に変更
   calendarView.maxDate = calendar.timeInMillis

   // 変更後の過去の選択可能日を取得
   val newMinDate = calendarView.minDate
   println("変更後の過去の選択可能日:" + format.format(newMinDate))

   // 変更後の未来の選択可能日を取得
   val newMaxDate = calendarView.maxDate
   println("変更後の未来の選択可能日:" + format.format(newMaxDate))
}

[出力結果]
初期の過去の選択可能日:1900/01/01
初期の未来の選択可能日:2100/12/31
変更後の過去の選択可能日:2020/02/13
変更後の未来の選択可能日:2020/03/18
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   tools:context=".MainActivity"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <CalendarView
       android:id="@+id/calendar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</LinearLayout>

過去の選択可能日を設定・取得するには、minDateを使用します。出力結果からわかるように、何も設定しなかった場合、1900/01/01まで遡って選択することができます。

未来の選択可能日を設定・取得するには、maxDateを使用します。何も設定しなかった場合、2100/12/31まで遡って選択することができます。

date同様、UNIX時間のミリ秒で、設定・取得を行います。

Point
  • 過去の選択可能日を設定・取得するには、minDateを使用する
  • 未来の選択可能日を設定・取得するには、maxDateを使用する

開始曜日を設定・取得する方法

続いて、カレンダーの開始曜日を設定・取得する方法を紹介致します。

以下は、カレンダーの開始曜日を水曜日に変更するサンプルコードです。

  • MainActivity.kt
  • activity_main.xml
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val calendarView = findViewById<CalendarView>(R.id.calendar)

   // 初期の開始曜日を取得
   val defaultFirstDayOfWeek = calendarView.firstDayOfWeek
   println("初期の開始曜日:" + defaultFirstDayOfWeek)

   // 開始曜日を水曜日に変更
   calendarView.firstDayOfWeek = Calendar.WEDNESDAY

   // 変更後の開始曜日を取得
   val newFirstDayOfWeek = calendarView.firstDayOfWeek
   println("変更後の開始曜日:" + newFirstDayOfWeek)
}

[出力結果]
初期の開始曜日:1
変更後の開始曜日:4
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   tools:context=".MainActivity"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <CalendarView
       android:id="@+id/calendar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</LinearLayout>

開始曜日を設定・取得するには、firstDayOfWeekを使用します。firstDayOfWeekには、Intで曜日を指定します。

Calendar.SUNDAY = 1
Calendar.MONDAY = 2
Calendar.TUESDAY = 3
Calendar.WEDNESDAY = 4
Calendar.THURSDAY = 5
Calendar.FRIDAY = 6
Calendar.SATURDAY = 7
Point
  • 開始曜日を設定・取得するには、firstDayOfWeekを使用する

日付選択イベントを受け取る方法

最後に、日付選択イベントを受け取る方法を紹介致します。日付選択イベントを受け取るには、setOnDateChangeListenerを実装します。

以下は、カレンダーの日付を選択すると、選択された日付がトーストで表示されるサンプルコードです。

  • MainActivity.kt
  • activity_main.xml
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val calendarView = findViewById<CalendarView>(R.id.calendar)

   // 日付変更イベントを追加
   calendarView.setOnDateChangeListener { view, year, month, dayOfMonth ->
       val date = "$year/$month/$dayOfMonth"
       Toast.makeText(this, date, Toast.LENGTH_SHORT).show()
   }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   tools:context=".MainActivity"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <CalendarView
       android:id="@+id/calendar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</LinearLayout>

setOnDateChangeListenerの後のブロック{ }内に、日付が選択された際に行いたい処理を実装します。また、ブロック内では、状態が変更されたCalendarView(サンプルコードのview)と、年月日(サンプルコードのyear、month、dayOfMonth)を受け取ることができます。

Point
  • 日付選択イベントを実装するには、setOnDateChangeListenerを使用する

まとめ

  • xmlでカレンダーを実装するには、<CalendarView/>タグを使用する
  • コードで実装するには、CalendarView()でインスタンスを生成した後、addView()で追加する
  • 選択日を設定・取得するには、dateを使用する
  • 過去の選択可能日を設定・取得するには、minDateを使用する
  • 未来の選択可能日を設定・取得するには、maxDateを使用する
  • 開始曜日を設定・取得するには、firstDayOfWeekを使用する
  • 日付選択イベントを実装するには、setOnDateChangeListenerを使用する