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 17package com.android.contacts.datepicker; 18 19// This is a fork of the standard Android DatePicker that additionally allows toggling the year 20// on/off. It uses some private API so that not everything has to be copied. 21 22import android.app.AlertDialog; 23import android.content.Context; 24import android.content.DialogInterface; 25import android.content.DialogInterface.OnClickListener; 26import android.os.Build; 27import android.os.Bundle; 28import android.text.TextUtils.TruncateAt; 29import android.view.LayoutInflater; 30import android.view.View; 31import android.widget.TextView; 32 33import com.android.contacts.R; 34import com.android.contacts.datepicker.DatePicker.OnDateChangedListener; 35 36import java.text.DateFormatSymbols; 37import java.util.Calendar; 38 39/** 40 * A simple dialog containing an {@link DatePicker}. 41 * 42 * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker 43 * tutorial</a>.</p> 44 */ 45public class DatePickerDialog extends AlertDialog implements OnClickListener, 46 OnDateChangedListener { 47 48 private static final String YEAR = "year"; 49 private static final String MONTH = "month"; 50 private static final String DAY = "day"; 51 private static final String YEAR_OPTIONAL = "year_optional"; 52 53 private final DatePicker mDatePicker; 54 private final OnDateSetListener mCallBack; 55 private final Calendar mCalendar; 56 private final java.text.DateFormat mTitleDateFormat; 57 private final String[] mWeekDays; 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 0 if the user has not specified a year 70 * @param monthOfYear The month that was set (0-11) for compatibility 71 * with {@link java.util.Calendar}. 72 * @param dayOfMonth The day of the month that was set. 73 */ 74 void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth); 75 } 76 77 /** 78 * @param context The context the dialog is to run in. 79 * @param callBack How the parent is notified that the date is set. 80 * @param year The initial year of the dialog 81 * @param monthOfYear The initial month of the dialog. 82 * @param dayOfMonth The initial day of the dialog. 83 */ 84 public DatePickerDialog(Context context, 85 OnDateSetListener callBack, 86 int year, 87 int monthOfYear, 88 int dayOfMonth) { 89 this(context, callBack, year, monthOfYear, dayOfMonth, false); 90 } 91 92 /** 93 * @param context The context the dialog is to run in. 94 * @param callBack How the parent is notified that the date is set. 95 * @param year The initial year of the dialog or 0 if no year has been specified 96 * @param monthOfYear The initial month of the dialog. 97 * @param dayOfMonth The initial day of the dialog. 98 * @param yearOptional Whether the year can be toggled by the user 99 */ 100 public DatePickerDialog(Context context, 101 OnDateSetListener callBack, 102 int year, 103 int monthOfYear, 104 int dayOfMonth, 105 boolean yearOptional) { 106 this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB 107 ? com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert 108 : com.android.internal.R.style.Theme_Dialog_Alert, 109 callBack, year, monthOfYear, dayOfMonth, yearOptional); 110 } 111 112 /** 113 * @param context The context the dialog is to run in. 114 * @param theme the theme to apply to this dialog 115 * @param callBack How the parent is notified that the date is set. 116 * @param year The initial year of the dialog or 0 if no year has been specified 117 * @param monthOfYear The initial month of the dialog. 118 * @param dayOfMonth The initial day of the dialog. 119 */ 120 public DatePickerDialog(Context context, 121 int theme, 122 OnDateSetListener callBack, 123 int year, 124 int monthOfYear, 125 int dayOfMonth) { 126 this(context, theme, callBack, year, monthOfYear, dayOfMonth, false); 127 } 128 129 /** 130 * @param context The context the dialog is to run in. 131 * @param theme the theme to apply to this dialog 132 * @param callBack How the parent is notified that the date is set. 133 * @param year The initial year of the dialog. 134 * @param monthOfYear The initial month of the dialog. 135 * @param dayOfMonth The initial day of the dialog. 136 * @param yearOptional Whether the year can be toggled by the user 137 */ 138 public DatePickerDialog(Context context, 139 int theme, 140 OnDateSetListener callBack, 141 int year, 142 int monthOfYear, 143 int dayOfMonth, 144 boolean yearOptional) { 145 super(context, theme); 146 147 mCallBack = callBack; 148 mInitialYear = year; 149 mInitialMonth = monthOfYear; 150 mInitialDay = dayOfMonth; 151 DateFormatSymbols symbols = new DateFormatSymbols(); 152 mWeekDays = symbols.getShortWeekdays(); 153 154 mTitleDateFormat = java.text.DateFormat. 155 getDateInstance(java.text.DateFormat.FULL); 156 mCalendar = Calendar.getInstance(); 157 updateTitle(mInitialYear, mInitialMonth, mInitialDay); 158 159 setButton(BUTTON_POSITIVE, context.getText(com.android.internal.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 173 public void show() { 174 super.show(); 175 176 /* Sometimes the full month is displayed causing the title 177 * to be very long, in those cases ensure it doesn't wrap to 178 * 2 lines (as that looks jumpy) and ensure we ellipsize the end. 179 */ 180 TextView title = (TextView) findViewById(com.android.internal.R.id.alertTitle); 181 title.setSingleLine(); 182 title.setEllipsize(TruncateAt.END); 183 } 184 185 public void onClick(DialogInterface dialog, int which) { 186 if (mCallBack != null) { 187 mDatePicker.clearFocus(); 188 mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), 189 mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); 190 } 191 } 192 193 public void onDateChanged(DatePicker view, int year, 194 int month, int day) { 195 updateTitle(year, month, day); 196 } 197 198 public void updateDate(int year, int monthOfYear, int dayOfMonth) { 199 mInitialYear = year; 200 mInitialMonth = monthOfYear; 201 mInitialDay = dayOfMonth; 202 mDatePicker.updateDate(year, monthOfYear, dayOfMonth); 203 } 204 205 private void updateTitle(int year, int month, int day) { 206 mCalendar.set(Calendar.YEAR, year); 207 mCalendar.set(Calendar.MONTH, month); 208 mCalendar.set(Calendar.DAY_OF_MONTH, day); 209 setTitle(mTitleDateFormat.format(mCalendar.getTime())); 210 } 211 212 @Override 213 public Bundle onSaveInstanceState() { 214 Bundle state = super.onSaveInstanceState(); 215 state.putInt(YEAR, mDatePicker.getYear()); 216 state.putInt(MONTH, mDatePicker.getMonth()); 217 state.putInt(DAY, mDatePicker.getDayOfMonth()); 218 state.putBoolean(YEAR_OPTIONAL, mDatePicker.isYearOptional()); 219 return state; 220 } 221 222 @Override 223 public void onRestoreInstanceState(Bundle savedInstanceState) { 224 super.onRestoreInstanceState(savedInstanceState); 225 int year = savedInstanceState.getInt(YEAR); 226 int month = savedInstanceState.getInt(MONTH); 227 int day = savedInstanceState.getInt(DAY); 228 boolean yearOptional = savedInstanceState.getBoolean(YEAR_OPTIONAL); 229 mDatePicker.init(year, month, day, yearOptional, this); 230 updateTitle(year, month, day); 231 } 232} 233