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