Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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 |
Brian Attwell | ee89164 | 2014-06-16 17:46:36 -0700 | [diff] [blame] | 20 | // on/off. |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 21 | |
| 22 | import android.app.AlertDialog; |
| 23 | import android.content.Context; |
| 24 | import android.content.DialogInterface; |
| 25 | import android.content.DialogInterface.OnClickListener; |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 26 | import android.os.Bundle; |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 27 | import android.view.LayoutInflater; |
| 28 | import android.view.View; |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 29 | |
Chiao Cheng | e0b2f1e | 2012-06-12 13:07:56 -0700 | [diff] [blame] | 30 | import com.android.contacts.R; |
| 31 | import com.android.contacts.datepicker.DatePicker.OnDateChangedListener; |
Gary Mai | 0a49afa | 2016-12-05 15:53:58 -0800 | [diff] [blame] | 32 | import com.android.contacts.util.DateUtils; |
Chiao Cheng | e0b2f1e | 2012-06-12 13:07:56 -0700 | [diff] [blame] | 33 | |
Daniel Lehmann | 11812c5 | 2012-03-29 17:50:29 -0700 | [diff] [blame] | 34 | import java.text.DateFormat; |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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 | |
Daniel Lehmann | 5a7a269 | 2012-08-03 21:39:01 -0700 | [diff] [blame] | 46 | /** Magic year that represents "no year" */ |
| 47 | public static int NO_YEAR = DatePicker.NO_YEAR; |
| 48 | |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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; |
Daniel Lehmann | 11812c5 | 2012-03-29 17:50:29 -0700 | [diff] [blame] | 56 | private final DateFormat mTitleDateFormat; |
| 57 | private final DateFormat mTitleNoYearDateFormat; |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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. |
Daniel Lehmann | 5a7a269 | 2012-08-03 21:39:01 -0700 | [diff] [blame] | 69 | * @param year The year that was set or {@link DatePickerDialog#NO_YEAR} if the user has |
| 70 | * not specified a year |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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 | */ |
| 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 | */ |
| 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. |
Daniel Lehmann | 5a7a269 | 2012-08-03 21:39:01 -0700 | [diff] [blame] | 96 | * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no year |
| 97 | * has been specified |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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 | */ |
| 102 | public DatePickerDialog(Context context, |
| 103 | OnDateSetListener callBack, |
| 104 | int year, |
| 105 | int monthOfYear, |
| 106 | int dayOfMonth, |
| 107 | boolean yearOptional) { |
Brian Attwell | ec0e096 | 2015-05-21 15:01:09 -0700 | [diff] [blame] | 108 | // Don't pass a theme id. Instead use the default alert dialog theme. |
| 109 | this(context, /* themeId = */ -1, callBack, year, monthOfYear, dayOfMonth, |
Brian Attwell | ee89164 | 2014-06-16 17:46:36 -0700 | [diff] [blame] | 110 | yearOptional); |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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. |
Daniel Lehmann | 5a7a269 | 2012-08-03 21:39:01 -0700 | [diff] [blame] | 117 | * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no year |
| 118 | * has been specified |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 119 | * @param monthOfYear The initial month of the dialog. |
| 120 | * @param dayOfMonth The initial day of the dialog. |
| 121 | */ |
| 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. |
Daniel Lehmann | 5a7a269 | 2012-08-03 21:39:01 -0700 | [diff] [blame] | 135 | * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no |
| 136 | * year has been specified. |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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 | */ |
| 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; |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 154 | |
Daniel Lehmann | 11812c5 | 2012-03-29 17:50:29 -0700 | [diff] [blame] | 155 | mTitleDateFormat = DateFormat.getDateInstance(DateFormat.FULL); |
Yorke Lee | c7ea6e9 | 2012-12-11 14:55:41 -0800 | [diff] [blame] | 156 | mTitleNoYearDateFormat = DateUtils.getLocalizedDateFormatWithoutYear(getContext()); |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 157 | updateTitle(mInitialYear, mInitialMonth, mInitialDay); |
| 158 | |
Brian Attwell | ee89164 | 2014-06-16 17:46:36 -0700 | [diff] [blame] | 159 | setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 160 | this); |
| 161 | setButton(BUTTON_NEGATIVE, context.getText(android.R.string.cancel), |
| 162 | (OnClickListener) null); |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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 |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 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 | |
Daniel Lehmann | 11812c5 | 2012-03-29 17:50:29 -0700 | [diff] [blame] | 181 | @Override |
| 182 | public void onDateChanged(DatePicker view, int year, int month, int day) { |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 183 | updateTitle(year, month, day); |
| 184 | } |
| 185 | |
| 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 | |
| 193 | private void updateTitle(int year, int month, int day) { |
Daniel Lehmann | 5a7a269 | 2012-08-03 21:39:01 -0700 | [diff] [blame] | 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); |
Daniel Lehmann | 11812c5 | 2012-03-29 17:50:29 -0700 | [diff] [blame] | 198 | final DateFormat dateFormat = |
Daniel Lehmann | 5a7a269 | 2012-08-03 21:39:01 -0700 | [diff] [blame] | 199 | year == NO_YEAR ? mTitleNoYearDateFormat : mTitleDateFormat; |
| 200 | setTitle(dateFormat.format(calendar.getTime())); |
Daniel Lehmann | 392ccec | 2010-11-01 20:50:03 -0700 | [diff] [blame] | 201 | } |
| 202 | |
| 203 | @Override |
| 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 |
| 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 | } |