日付選択
〜 Android Studio の使い方 12 〜
2023-06-09 作成 福島
TOP > androidstudio > datepicker

使用ツール

    Android Studio Flamingo | 2022.2.1 Patch 2  


1. 通常のプロジェクトを作成する。

ここでは日付選択を行うので、画面の存在するプロジェクトを作成する。
「Empty Activity」「Empty Views Activity」等のプロジェクトが対象。
「No Activity」でも構わないが、Default Activity の追加が必要になるので、ここでは割愛する。(選択しない)


2. 日付選択処理を追加。

クラス MainActivity に以下を記述する
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


final int nowY=2021, nowM=5, nowD=15; final int minY=2019, minM=2, minD=4; final int maxY=2023, maxM=6, maxD=9; Calendar calMin = Calendar.getInstance(); // java.util の Calendar なら API24 未満でも使える Calendar calMax = Calendar.getInstance(); // android.icu.util だと API24 以上が必要 calMin.set(minY, minM - 1, minD); calMax.set(maxY, maxM - 1, maxD); doDatePickerDialog( nowY, nowM, nowD, calMin, calMax); // 新API用 (下記メソッドを参照) doDatePickerFragment(nowY, nowM, nowD, calMin, calMax); // 旧API用 ( 〃 )
}
boolean doDatePickerDialog(int y, int m, int d, Calendar calMin, Calendar calMax) { if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N) return false; // DatePickerDialog は API24 (Android7.0) 以上が必要 DatePickerDialog datePickerDialog = new DatePickerDialog(this); // DatePickerDialog に制限 (最小日付 / 最大日付 / 初期日付) を設定する DatePicker datePicker = datePickerDialog.getDatePicker(); datePicker.setMinDate(calMin.getTimeInMillis()); datePicker.setMaxDate(calMax.getTimeInMillis()); datePicker.updateDate(y, m - 1, d); // OK / キャンセル時のリスナを設定 class OnOkCancel implements DatePickerDialog.OnDateSetListener, DialogInterface.OnCancelListener { @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { Log.d("OnOkCancel", String.format("%04d-%02d-%02d", year, month + 1, dayOfMonth)); } @Override public void onCancel(DialogInterface dialog) { Log.d("OnOkCancel", "Cancel"); } } datePickerDialog.setOnDateSetListener(new OnOkCancel()); datePickerDialog.setOnCancelListener( new OnOkCancel()); datePickerDialog.show(); return true; }

void doDatePickerFragment(int y, int m, int d, Calendar calMin, Calendar calMax) { // こちらは DatePickerFragment を使うやり方 (API24 未満にも対応) DatePickerFragment datePickerFragment = new DatePickerFragment(); long[] arr = {y, m, d, calMin.getTimeInMillis(), calMax.getTimeInMillis()}; // 初期値を ViewModel で渡す LongArray longArray = new ViewModelProvider(this).get(LongArray.class); longArray.set(arr); // OK / キャンセル選択時のリスナを設定 class OnOkCancel implements DatePickerFragment.OnOkCancelListener { @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { Log.d("OnOkCancel", String.format("%04d-%02d-%02d", year, month + 1, dayOfMonth)); } @Override public void onCancel(DialogInterface dialog) { Log.d("OnOkCancel", "Cancel"); } } datePickerFragment.setOnDateSetListener(new OnOkCancel()); datePickerFragment.show(getSupportFragmentManager(), ""); } // 初期値を渡すためのクラス public static class LongArray extends ViewModel { long[] array; long[] get() { return array; } void set(long[] val) { array = val; } } // DatePickerDialog を定義 // 基本的に本家の推奨に従っているけど、使いやすくしています。 public static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // 親画面から初期値を受領する LongArray longArray = new ViewModelProvider(requireActivity()).get(LongArray.class); long[] arr = longArray.get(); DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, (int)arr[0], // Year (int)arr[1]-1, // Month (int)arr[2] // DayOfMonth ); // 選択の範囲を制限しても、月中で範囲外の日付を選択できてしまう // (端末固有のバグ? API24 では再現しない) ので、[OK] 押下時の対処が必要 DatePicker datePicker = datePickerDialog.getDatePicker(); datePicker.setMinDate(arr[3]); datePicker.setMaxDate(arr[4]); return datePickerDialog; } // OK / キャンセル のリスナ I/F を定義 public interface OnOkCancelListener { void onCancel(DialogInterface dialog); void onDateSet(DatePicker view, int year, int month, int dayOfMonth); } private OnOkCancelListener onOkCancelListener = null; @Override public void onCancel(@NonNull DialogInterface dialog) { // [ キャンセル ] ボタンで呼ばれるメソッド onOkCancelListener.onCancel(dialog); } @Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { // [ OK ] ボタンで呼ばれるメソッド onOkCancelListener.onDateSet(view, year, month, dayOfMonth); } public void setOnDateSetListener(OnOkCancelListener listener) { // OK / キャンセル のリスナを登録 this.onOkCancelListener = listener; } }
}