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