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. It uses some private API so that not everything has to be copied. 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.Build; 27 import android.os.Bundle; 28 import android.text.TextUtils.TruncateAt; 29 import android.view.LayoutInflater; 30 import android.view.View; 31 import android.widget.TextView; 32 33 import com.android.contacts.R; 34 import com.android.contacts.datepicker.DatePicker.OnDateChangedListener; 35 36 import java.text.DateFormatSymbols; 37 import 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 */ 45 public 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 */ onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)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 */ DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)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 */ DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)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 */ DatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)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 */ DatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)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 show()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 onClick(DialogInterface dialog, int which)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 onDateChanged(DatePicker view, int year, int month, int day)193 public void onDateChanged(DatePicker view, int year, 194 int month, int day) { 195 updateTitle(year, month, day); 196 } 197 updateDate(int year, int monthOfYear, int dayOfMonth)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 updateTitle(int year, int month, int day)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 onSaveInstanceState()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 onRestoreInstanceState(Bundle savedInstanceState)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