繰り返しのある予定表示に対応したカレンダーを作った

これはAndroid Advent Calendar 2015の10日目の記事です。

はじめに

去年のAndroid Advent Calendarは25日目を担当したので、今年は無難な日付に収まることにしました。今回は繰り返しのある予定表示に対応したカレンダーライブラリを作ったので、その紹介をさせていただきます。

リポジトリ

繰り返しのある予定について

予定の繰り返しをどのように表現するかはRFC2445にて定義されており、一般にRRuleと呼ばれています。RRuleは予定の繰り返し周期や繰り返し曜日などを表現することができ、本ライブラリはそのRRuleを用いた予定の繰り返しに対応しています。例えば、毎週月曜日という繰り返し条件は以下のRRuleで表現されます。

FREQ=WEEKLY;BYDAY=MO

もう少し具体的な例を考えてみます。 予定の開始日時が2015-09-05T10:00:00.000Zで、RRuleがFREQ=WEEKLYとし、予定の展開範囲を2015-09-01T00:00:00.000Zから2015-09-30T23:59:59.999Zとします。この場合は、以下の4つの予定に展開されます。

  • 2015-09-05T10:00:00.000Z
  • 2015-09-12T10:00:00.000Z
  • 2015-09-19T10:00:00.000Z
  • 2015-09-26T10:00:00.000Z

機能紹介

土日の色付け

以下のように土曜日は青、日曜日は赤で表示されます。

f:id:yuyakaido:20171210092914p:plain

予定の表示

予定がある日には以下のようにドットが表示されます。最大2つまで表示され、3つ以上ある場合には右下にプラスマークが付きます。

f:id:yuyakaido:20171210092938p:plain

予定の色分け

予定には任意の色を設定することが出来ます。デフォルトでは赤、オレンジ、黄、緑、ティファニーブルー、ライトブルー、青、紫、ピンク、藍のテーマカラーを用意してあります。詳しくはThemeをご参照ください。

f:id:yuyakaido:20171210092949p:plain

テーマカラー

本ライブラリでは日付セルをタップするとその日付がテーマカラーにもとづいてハイライトされます。ライブラリの初期化時にテーマカラーを渡すことで切り替えが可能です。

f:id:yuyakaido:20171210093001p:plain

繰り返しのある予定の表示

本ライブラリではRRuleをもとに自動的に予定が展開されて表示されます。繰り返しの周期は毎日(FREQ=DAILY)毎週(FREQ=WEEKLY)毎月(FREQ=MONTHLY)毎年(FREQ=YEARLY)に対応しています。例えば、開始時間が2015-08-01T00:00:00.000Z毎週繰り返し(FREQ=WEEKLY)というRRuleを持った予定と開始時間が2015-08-02T00:00:00.000Z隔週繰り返し(FREQ=WEEKLY;INTERVAL=2)という2つの予定を設定すると以下のように表示されます。

f:id:yuyakaido:20171210093013p:plain

連日予定の帯表示

複数日にわたる予定の場合には、以下のように帯表示となります。予定が被っている場合には重なって表示されます。

f:id:yuyakaido:20171210093028p:plain

使い方紹介

カレンダーの表示

カレンダー本体はCouplesCalendarFragmentで実装されています。カレンダーを表示するだけであれば以下のようにFragmentTransactionでCouplesCalendarFragmentを表示するだけでOKです。

CouplesCalendarFragment fragment = CouplesCalendarFragment.newInstance();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.main_activity_fragment_container, fragment);
transaction.commit();

予定の表示

以下のように任意のオブジェクトにCouplesCalendarEventを付与することでライブラリで表示可能な予定オブジェクトとなります。CouplesCalendarFragmentのsetEventsメソッドに予定オブジェクトのリストを渡すことで予定が表示されます。

public class SampleEvent implements CouplesCalendarEvent {

    private Date mStartAt;
    private Date mEndAt;
    private String mRRule;
    private int mEventColor;

    public void setStartAt(Date startAt) {
        mStartAt = startAt;
    }

    @Override
    public Date getStartAt() {
        return mStartAt;
    }

    public void setEndAt(Date endAt) {
        mEndAt = endAt;
    }

    @Override
    public Date getEndAt() {
        return mEndAt;
    }

    public void setRecurrenceRule(String recurrenceRule) {
        mRRule = recurrenceRule;
    }

    @Override
    public String getRecurrenceRule() {
        return mRRule;
    }

    public void setEventColor(int eventColor) {
        mEventColor = eventColor;
    }

    @Override
    public int getEventColor() {
        return mEventColor;
    }

}

CouplesCalendarEventには以下の4つの情報を取得するためにメソッドが定義されています。

  • 予定の開始時間
  • 予定の終了時間
  • 予定の繰り返し条件
  • 予定の色

このうちでカレンダーに予定を表示するためには最低限以下の情報が必要になります。

  • 予定の開始時間
  • 予定の終了時間

予定の色を設定しなかった場合はデフォルトカラーが設定され、繰り返し条件(RRule)に何も設定しなかった場合は繰り返しのない予定として扱われます。