1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.contacts.datepicker; 18 19 // This is a fork of the standard Android DatePicker that additionally allows toggling the year 20 // on/off. 21 22 import android.app.AlertDialog; 23 import android.content.Context; 24 import android.content.DialogInterface; 25 import android.content.DialogInterface.OnClickListener; 26 import android.os.Bundle; 27 import android.view.LayoutInflater; 28 import android.view.View; 29 30 import com.android.contacts.R; 31 import com.android.contacts.datepicker.DatePicker.OnDateChangedListener; 32 import com.android.contacts.util.DateUtils; 33 34 import java.text.DateFormat; 35 import java.util.Calendar; 36 37 /** 38 * A simple dialog containing an {@link DatePicker}. 39 * 40 * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker 41 * tutorial</a>.</p> 42 */ 43 public class DatePickerDialog extends AlertDialog implements OnClickListener, 44 OnDateChangedListener { 45 46 /** Magic year that represents "no year" */ 47 public static int NO_YEAR = DatePicker.NO_YEAR; 48 49 private static final String YEAR = "year"; 50 private static final String MONTH = "month"; 51 private static final String DAY = "day"; 52 private static final String YEAR_OPTIONAL = "year_optional"; 53 54 private final DatePicker mDatePicker; 55 private final OnDateSetListener mCallBack; 56 private final DateFormat mTitleDateFormat; 57 private final DateFormat mTitleNoYearDateFormat; 58 59 private int mInitialYear; 60 private int mInitialMonth; 61 private int mInitialDay; 62 63 /** 64 * The callback used to indicate the user is done filling in the date. 65 */ 66 public interface OnDateSetListener { 67 /** 68 * @param view The view associated with this listener. 69 * @param year The year that was set or {@link DatePickerDialog#NO_YEAR} if the user has 70 * not specified a year 71 * @param monthOfYear The month that was set (0-11) for compatibility 72 * with {@link java.util.Calendar}. 73 * @param dayOfMonth The day of the month that was set. 74 */ onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)75 void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth); 76 } 77 78 /** 79 * @param context The context the dialog is to run in. 80 * @param callBack How the parent is notified that the date is set. 81 * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no year 82 * has been specified 83 * @param monthOfYear The initial month of the dialog. 84 * @param dayOfMonth The initial day of the dialog. 85 * @param yearOptional Whether the year can be toggled by the user 86 */ DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)87 public DatePickerDialog(Context context, 88 OnDateSetListener callBack, 89 int year, 90 int monthOfYear, 91 int dayOfMonth, 92 boolean yearOptional) { 93 // Don't pass a theme id. Instead use the default alert dialog theme. 94 this(context, /* themeId = */ 0, callBack, year, monthOfYear, dayOfMonth, 95 yearOptional); 96 } 97 98 /** 99 * @param context The context the dialog is to run in. 100 * @param theme the theme to apply to this dialog 101 * @param callBack How the parent is notified that the date is set. 102 * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no 103 * year has been specified. 104 * @param monthOfYear The initial month of the dialog. 105 * @param dayOfMonth The initial day of the dialog. 106 * @param yearOptional Whether the year can be toggled by the user 107 */ DatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)108 public DatePickerDialog(Context context, 109 int theme, 110 OnDateSetListener callBack, 111 int year, 112 int monthOfYear, 113 int dayOfMonth, 114 boolean yearOptional) { 115 super(context, theme); 116 117 mCallBack = callBack; 118 mInitialYear = year; 119 mInitialMonth = monthOfYear; 120 mInitialDay = dayOfMonth; 121 122 mTitleDateFormat = DateFormat.getDateInstance(DateFormat.FULL); 123 mTitleNoYearDateFormat = DateUtils.getLocalizedDateFormatWithoutYear(getContext()); 124 updateTitle(mInitialYear, mInitialMonth, mInitialDay); 125 126 setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), 127 this); 128 setButton(BUTTON_NEGATIVE, context.getText(android.R.string.cancel), 129 (OnClickListener) null); 130 131 LayoutInflater inflater = 132 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 133 View view = inflater.inflate(R.layout.date_picker_dialog, null); 134 setView(view); 135 mDatePicker = (DatePicker) view.findViewById(R.id.datePicker); 136 mDatePicker.init(mInitialYear, mInitialMonth, mInitialDay, yearOptional, this); 137 } 138 139 @Override onClick(DialogInterface dialog, int which)140 public void onClick(DialogInterface dialog, int which) { 141 if (mCallBack != null) { 142 mDatePicker.clearFocus(); 143 mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), 144 mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); 145 } 146 } 147 148 @Override onDateChanged(DatePicker view, int year, int month, int day)149 public void onDateChanged(DatePicker view, int year, int month, int day) { 150 updateTitle(year, month, day); 151 } 152 updateTitle(int year, int month, int day)153 private void updateTitle(int year, int month, int day) { 154 final Calendar calendar = Calendar.getInstance(); 155 calendar.set(Calendar.YEAR, year); 156 calendar.set(Calendar.MONTH, month); 157 calendar.set(Calendar.DAY_OF_MONTH, day); 158 final DateFormat dateFormat = 159 year == NO_YEAR ? mTitleNoYearDateFormat : mTitleDateFormat; 160 setTitle(dateFormat.format(calendar.getTime())); 161 } 162 163 @Override onSaveInstanceState()164 public Bundle onSaveInstanceState() { 165 Bundle state = super.onSaveInstanceState(); 166 state.putInt(YEAR, mDatePicker.getYear()); 167 state.putInt(MONTH, mDatePicker.getMonth()); 168 state.putInt(DAY, mDatePicker.getDayOfMonth()); 169 state.putBoolean(YEAR_OPTIONAL, mDatePicker.isYearOptional()); 170 return state; 171 } 172 173 @Override onRestoreInstanceState(Bundle savedInstanceState)174 public void onRestoreInstanceState(Bundle savedInstanceState) { 175 super.onRestoreInstanceState(savedInstanceState); 176 int year = savedInstanceState.getInt(YEAR); 177 int month = savedInstanceState.getInt(MONTH); 178 int day = savedInstanceState.getInt(DAY); 179 boolean yearOptional = savedInstanceState.getBoolean(YEAR_OPTIONAL); 180 mDatePicker.init(year, month, day, yearOptional, this); 181 updateTitle(year, month, day); 182 } 183 } 184