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 82 * @param monthOfYear The initial month of the dialog. 83 * @param dayOfMonth The initial day of the dialog. 84 */ DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)85 public DatePickerDialog(Context context, 86 OnDateSetListener callBack, 87 int year, 88 int monthOfYear, 89 int dayOfMonth) { 90 this(context, callBack, year, monthOfYear, dayOfMonth, false); 91 } 92 93 /** 94 * @param context The context the dialog is to run in. 95 * @param callBack How the parent is notified that the date is set. 96 * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no year 97 * has been specified 98 * @param monthOfYear The initial month of the dialog. 99 * @param dayOfMonth The initial day of the dialog. 100 * @param yearOptional Whether the year can be toggled by the user 101 */ DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)102 public DatePickerDialog(Context context, 103 OnDateSetListener callBack, 104 int year, 105 int monthOfYear, 106 int dayOfMonth, 107 boolean yearOptional) { 108 // Don't pass a theme id. Instead use the default alert dialog theme. 109 this(context, /* themeId = */ -1, callBack, year, monthOfYear, dayOfMonth, 110 yearOptional); 111 } 112 113 /** 114 * @param context The context the dialog is to run in. 115 * @param theme the theme to apply to this dialog 116 * @param callBack How the parent is notified that the date is set. 117 * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no year 118 * has been specified 119 * @param monthOfYear The initial month of the dialog. 120 * @param dayOfMonth The initial day of the dialog. 121 */ DatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)122 public DatePickerDialog(Context context, 123 int theme, 124 OnDateSetListener callBack, 125 int year, 126 int monthOfYear, 127 int dayOfMonth) { 128 this(context, theme, callBack, year, monthOfYear, dayOfMonth, false); 129 } 130 131 /** 132 * @param context The context the dialog is to run in. 133 * @param theme the theme to apply to this dialog 134 * @param callBack How the parent is notified that the date is set. 135 * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no 136 * year has been specified. 137 * @param monthOfYear The initial month of the dialog. 138 * @param dayOfMonth The initial day of the dialog. 139 * @param yearOptional Whether the year can be toggled by the user 140 */ DatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)141 public DatePickerDialog(Context context, 142 int theme, 143 OnDateSetListener callBack, 144 int year, 145 int monthOfYear, 146 int dayOfMonth, 147 boolean yearOptional) { 148 super(context, theme); 149 150 mCallBack = callBack; 151 mInitialYear = year; 152 mInitialMonth = monthOfYear; 153 mInitialDay = dayOfMonth; 154 155 mTitleDateFormat = DateFormat.getDateInstance(DateFormat.FULL); 156 mTitleNoYearDateFormat = DateUtils.getLocalizedDateFormatWithoutYear(getContext()); 157 updateTitle(mInitialYear, mInitialMonth, mInitialDay); 158 159 setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), 160 this); 161 setButton(BUTTON_NEGATIVE, context.getText(android.R.string.cancel), 162 (OnClickListener) null); 163 164 LayoutInflater inflater = 165 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 166 View view = inflater.inflate(R.layout.date_picker_dialog, null); 167 setView(view); 168 mDatePicker = (DatePicker) view.findViewById(R.id.datePicker); 169 mDatePicker.init(mInitialYear, mInitialMonth, mInitialDay, yearOptional, this); 170 } 171 172 @Override onClick(DialogInterface dialog, int which)173 public void onClick(DialogInterface dialog, int which) { 174 if (mCallBack != null) { 175 mDatePicker.clearFocus(); 176 mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), 177 mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); 178 } 179 } 180 181 @Override onDateChanged(DatePicker view, int year, int month, int day)182 public void onDateChanged(DatePicker view, int year, int month, int day) { 183 updateTitle(year, month, day); 184 } 185 updateDate(int year, int monthOfYear, int dayOfMonth)186 public void updateDate(int year, int monthOfYear, int dayOfMonth) { 187 mInitialYear = year; 188 mInitialMonth = monthOfYear; 189 mInitialDay = dayOfMonth; 190 mDatePicker.updateDate(year, monthOfYear, dayOfMonth); 191 } 192 updateTitle(int year, int month, int day)193 private void updateTitle(int year, int month, int day) { 194 final Calendar calendar = Calendar.getInstance(); 195 calendar.set(Calendar.YEAR, year); 196 calendar.set(Calendar.MONTH, month); 197 calendar.set(Calendar.DAY_OF_MONTH, day); 198 final DateFormat dateFormat = 199 year == NO_YEAR ? mTitleNoYearDateFormat : mTitleDateFormat; 200 setTitle(dateFormat.format(calendar.getTime())); 201 } 202 203 @Override onSaveInstanceState()204 public Bundle onSaveInstanceState() { 205 Bundle state = super.onSaveInstanceState(); 206 state.putInt(YEAR, mDatePicker.getYear()); 207 state.putInt(MONTH, mDatePicker.getMonth()); 208 state.putInt(DAY, mDatePicker.getDayOfMonth()); 209 state.putBoolean(YEAR_OPTIONAL, mDatePicker.isYearOptional()); 210 return state; 211 } 212 213 @Override onRestoreInstanceState(Bundle savedInstanceState)214 public void onRestoreInstanceState(Bundle savedInstanceState) { 215 super.onRestoreInstanceState(savedInstanceState); 216 int year = savedInstanceState.getInt(YEAR); 217 int month = savedInstanceState.getInt(MONTH); 218 int day = savedInstanceState.getInt(DAY); 219 boolean yearOptional = savedInstanceState.getBoolean(YEAR_OPTIONAL); 220 mDatePicker.init(year, month, day, yearOptional, this); 221 updateTitle(year, month, day); 222 } 223 } 224