Androidアプリ開発 Material design Googleカレンダー風のCalendarダイアログを作成する

2016年07月11日(編集2016年07月12日)
このエントリーをはてなブックマークに追加

Androidアプリでは、Calendarダイアログから日付入力をさせたい場合があります。
この記事は、Calendarダイアログの作成方法を記載した記事です。

環境はAndroid 6.0 (API level 23) です。

環境

  • OS X Yosemite
  • Oracle jdk version 1.8.0_72
  • Android Studio 2.1.2
  • android sdk 23

難易度

初心者向け

サンプルコード

Android-Material-Design-Demo

Googleカレンダー

純正のGoogleカレンダーアプリでは、日付選択時に以下のCalendarダイアログが表示されます。

Googleカレンダー

この記事では、上記のCalendarダイアログを実装します。

実装

まず、DialogFragmentを継承したDatePickerDialogFragmentを作成します。

{project_folder}/ui/DatePickerDialogFragment.java
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.widget.DatePicker;

public class DatePickerDialogFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

    public static DatePickerDialogFragment newInstance(int year, int month, int dayOfMonth) {
        DatePickerDialogFragment frag = new DatePickerDialogFragment();
        Bundle args = new Bundle();
        args.putInt("year", year);
        args.putInt("month", month);
        args.putInt("dayOfMonth", dayOfMonth);
        frag.setArguments(args);
        return frag;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int year = getArguments().getInt("year");
        int month = getArguments().getInt("month");
        int dayOfMonth = getArguments().getInt("dayOfMonth");

        DatePickerDialog datePickerDialog = new DatePickerDialog(
                getActivity(), this, year, month, dayOfMonth);

        return datePickerDialog;
    }

    @Override
    public void onDateSet(DatePicker datePicker, int year, int month, int dayOfMonth) {
        Activity activity = getActivity();
        if (activity instanceof CalenderInputActivity) {
            ((CalenderInputActivity)activity).setDate(year, month, dayOfMonth);
        }
    }

}
        

■ 実装の解説

1. implements DatePickerDialog.OnDateSetListener

DatePickerDialog.OnDateSetListenerインンターフェースを実装します。

public class DatePickerDialogFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener
        

オーバーライドしたonDateSetメソッドで、日付選択の結果を取得します。

@Override
public void onDateSet(DatePicker datePicker, int year, int month, int dayOfMonth) {
    Activity activity = getActivity();
    if (activity instanceof CalenderInputActivity) {
        ((CalenderInputActivity)activity).setDate(year, month, dayOfMonth);
    }
}
        

ここでは、呼び出し元のActivityのsetDateメソッドを呼び出しています。

呼びだし元実装

上記で実装したDatePickerDialogFragmentをActivityクラスで呼びだします。
Fragmentを利用している場合は、interfaceのメソッドからActivity側のメソッドを呼び出します。

{project_folder}/ui/CalenderInputActivity.java
package com.java_lang_programming.android_material_design_demo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

import com.java_lang_programming.android_material_design_demo.ui.DatePickerDialogFragment;

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class CalenderInputActivity extends AppCompatActivity {

    private TextView mDate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calender_input);
        // Set up the login form.
        mDate = (TextView) findViewById(R.id.date);
        mDate.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                String date = mDate.getText().toString();

                int year = 0;
                int month = 0;
                int dayOfMonth = 0;
                if (TextUtils.isEmpty(date)) {
                    Calendar calendar = Calendar.getInstance();
                    year = calendar.get(Calendar.YEAR);
                    month = calendar.get(Calendar.MONTH);
                    dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
                } else {
                    year = Integer.valueOf(date.substring(0, 4));
                    month = Integer.valueOf(date.substring(5, 7));
                    month = month - 1;
                    dayOfMonth = Integer.valueOf(date.substring(8, 10));
                }
                showDatePickerDialog(year, month, dayOfMonth);
            }
        });

    }

    public void showDatePickerDialog(int year, int month, int dayOfMonth) {
        DatePickerDialogFragment dialog = DatePickerDialogFragment.newInstance(year, month, dayOfMonth);
        dialog.show(getSupportFragmentManager(), "datePicker");
    }

    public void setDate(int year, int month, int dayOfMonth) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month, dayOfMonth);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        mDate.setText(sdf.format(cal.getTime()));
    }
}
        

■ 実装の解説

1. showDatePickerDialog

getSupportFragmentManager()でactivityとFragmentを関連付けます。

DatePickerDialogFragment dialog = DatePickerDialogFragment.newInstance(year, month, dayOfMonth);
dialog.show(getSupportFragmentManager(), "datePicker");
        

これでDatePickerDialogFragmentが呼び出せます。

DatePickerDialogFragment

2. データ設定

DatePickerDialogFragmentで取得したデータを設定します。
onDateSetメソッドから呼び出します。

public void setDate(int year, int month, int dayOfMonth) {
    Calendar cal = Calendar.getInstance();
    cal.set(year, month, dayOfMonth);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    mDate.setText(sdf.format(cal.getTime()));
}
        
set data

ビルドして実行

実装を終えたら、ビルドしてアプリを実行します。

Sample App

まとめ

DatePickerDialogを使うと、Googleカレンダー風のCalendarダイアログを利用することができます。
自作するとかなりの工数がかかるので、なるべくデフォルトのCalendarダイアログを利用しましょう。

関連記事

タグ検索で調べてみよう

Android6.0 UI