• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.contacts.R;
23 import com.android.contacts.datepicker.DatePicker.OnDateChangedListener;
24 import com.android.contacts.util.DateUtils;
25 
26 import android.app.AlertDialog;
27 import android.content.Context;
28 import android.content.DialogInterface;
29 import android.content.DialogInterface.OnClickListener;
30 import android.os.Build;
31 import android.os.Bundle;
32 import android.text.TextUtils.TruncateAt;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.widget.TextView;
36 
37 import java.text.DateFormat;
38 import java.text.SimpleDateFormat;
39 import java.util.Calendar;
40 
41 /**
42  * A simple dialog containing an {@link DatePicker}.
43  *
44  * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
45  * tutorial</a>.</p>
46  */
47 public class DatePickerDialog extends AlertDialog implements OnClickListener,
48         OnDateChangedListener {
49 
50     private static final String YEAR = "year";
51     private static final String MONTH = "month";
52     private static final String DAY = "day";
53     private static final String YEAR_OPTIONAL = "year_optional";
54 
55     private final DatePicker mDatePicker;
56     private final OnDateSetListener mCallBack;
57     private final Calendar mCalendar;
58     private final DateFormat mTitleDateFormat;
59     private final DateFormat mTitleNoYearDateFormat;
60 
61     private int mInitialYear;
62     private int mInitialMonth;
63     private int mInitialDay;
64 
65     /**
66      * The callback used to indicate the user is done filling in the date.
67      */
68     public interface OnDateSetListener {
69         /**
70          * @param view The view associated with this listener.
71          * @param year The year that was set or 0 if the user has not specified a year
72          * @param monthOfYear The month that was set (0-11) for compatibility
73          *  with {@link java.util.Calendar}.
74          * @param dayOfMonth The day of the month that was set.
75          */
onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)76         void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth);
77     }
78 
79     /**
80      * @param context The context the dialog is to run in.
81      * @param callBack How the parent is notified that the date is set.
82      * @param year The initial year of the dialog
83      * @param monthOfYear The initial month of the dialog.
84      * @param dayOfMonth The initial day of the dialog.
85      */
DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)86     public DatePickerDialog(Context context,
87             OnDateSetListener callBack,
88             int year,
89             int monthOfYear,
90             int dayOfMonth) {
91         this(context, callBack, year, monthOfYear, dayOfMonth, false);
92     }
93 
94     /**
95      * @param context The context the dialog is to run in.
96      * @param callBack How the parent is notified that the date is set.
97      * @param year The initial year of the dialog or 0 if no year 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         this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
109                         ? com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert
110                         : com.android.internal.R.style.Theme_Dialog_Alert,
111                 callBack, year, monthOfYear, dayOfMonth, yearOptional);
112     }
113 
114     /**
115      * @param context The context the dialog is to run in.
116      * @param theme the theme to apply to this dialog
117      * @param callBack How the parent is notified that the date is set.
118      * @param year The initial year of the dialog or 0 if no year 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.
136      * @param monthOfYear The initial month of the dialog.
137      * @param dayOfMonth The initial day of the dialog.
138      * @param yearOptional Whether the year can be toggled by the user
139      */
DatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)140     public DatePickerDialog(Context context,
141             int theme,
142             OnDateSetListener callBack,
143             int year,
144             int monthOfYear,
145             int dayOfMonth,
146             boolean yearOptional) {
147         super(context, theme);
148 
149         mCallBack = callBack;
150         mInitialYear = year;
151         mInitialMonth = monthOfYear;
152         mInitialDay = dayOfMonth;
153 
154         mTitleDateFormat = DateFormat.getDateInstance(DateFormat.FULL);
155         mTitleNoYearDateFormat = new SimpleDateFormat(
156                 DateUtils.isMonthBeforeDay(getContext()) ? "MMMM dd" : "dd MMMM");
157         mCalendar = Calendar.getInstance();
158         updateTitle(mInitialYear, mInitialMonth, mInitialDay);
159 
160         setButton(BUTTON_POSITIVE, context.getText(com.android.internal.R.string.date_time_set),
161                 this);
162         setButton(BUTTON_NEGATIVE, context.getText(android.R.string.cancel),
163                 (OnClickListener) null);
164 
165         LayoutInflater inflater =
166                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
167         View view = inflater.inflate(R.layout.date_picker_dialog, null);
168         setView(view);
169         mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
170         mDatePicker.init(mInitialYear, mInitialMonth, mInitialDay, yearOptional, this);
171     }
172 
173     @Override
show()174     public void show() {
175         super.show();
176 
177         /* Sometimes the full month is displayed causing the title
178          * to be very long, in those cases ensure it doesn't wrap to
179          * 2 lines (as that looks jumpy) and ensure we ellipsize the end.
180          */
181         TextView title = (TextView) findViewById(com.android.internal.R.id.alertTitle);
182         title.setSingleLine();
183         title.setEllipsize(TruncateAt.END);
184     }
185 
186     @Override
onClick(DialogInterface dialog, int which)187     public void onClick(DialogInterface dialog, int which) {
188         if (mCallBack != null) {
189             mDatePicker.clearFocus();
190             mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
191                     mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
192         }
193     }
194 
195     @Override
onDateChanged(DatePicker view, int year, int month, int day)196     public void onDateChanged(DatePicker view, int year, int month, int day) {
197         updateTitle(year, month, day);
198     }
199 
updateDate(int year, int monthOfYear, int dayOfMonth)200     public void updateDate(int year, int monthOfYear, int dayOfMonth) {
201         mInitialYear = year;
202         mInitialMonth = monthOfYear;
203         mInitialDay = dayOfMonth;
204         mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
205     }
206 
updateTitle(int year, int month, int day)207     private void updateTitle(int year, int month, int day) {
208         mCalendar.set(Calendar.YEAR, year);
209         mCalendar.set(Calendar.MONTH, month);
210         mCalendar.set(Calendar.DAY_OF_MONTH, day);
211         final DateFormat dateFormat =
212                 year == 0 ? mTitleNoYearDateFormat : mTitleDateFormat;
213         setTitle(dateFormat.format(mCalendar.getTime()));
214     }
215 
216     @Override
onSaveInstanceState()217     public Bundle onSaveInstanceState() {
218         Bundle state = super.onSaveInstanceState();
219         state.putInt(YEAR, mDatePicker.getYear());
220         state.putInt(MONTH, mDatePicker.getMonth());
221         state.putInt(DAY, mDatePicker.getDayOfMonth());
222         state.putBoolean(YEAR_OPTIONAL, mDatePicker.isYearOptional());
223         return state;
224     }
225 
226     @Override
onRestoreInstanceState(Bundle savedInstanceState)227     public void onRestoreInstanceState(Bundle savedInstanceState) {
228         super.onRestoreInstanceState(savedInstanceState);
229         int year = savedInstanceState.getInt(YEAR);
230         int month = savedInstanceState.getInt(MONTH);
231         int day = savedInstanceState.getInt(DAY);
232         boolean yearOptional = savedInstanceState.getBoolean(YEAR_OPTIONAL);
233         mDatePicker.init(year, month, day, yearOptional, this);
234         updateTitle(year, month, day);
235     }
236 }
237