Android 自定義DatePickerDialog解決低版本手機以及部分Android系統個性化日期輸入控件后導致的bug.
程序開發中,碰到一些手機顯示日期輸入對話框框顯示不一致的問題,有些還會導致異常退出,故此自定義了日期輸入框的樣式解決問題。
1 package packageName.widget; 2 3 import java.util.Calendar; 4 5 import android.annotation.SuppressLint; 6 import android.app.AlertDialog; 7 import android.app.DatePickerDialog; 8 import android.content.Context; 9 import android.content.DialogInterface; 10 import android.content.DialogInterface.OnClickListener; 11 import android.os.Bundle; 12 import android.text.format.DateUtils; 13 import android.view.LayoutInflater; 14 import android.view.View; 15 import android.widget.DatePicker; 16 import android.widget.DatePicker.OnDateChangedListener; 17 18 import packageName.R; 19 20 /** 21 * @author homlee 22 * 23 */ 24 public class MyDatePickerDialog extends AlertDialog implements OnClickListener, 25 OnDateChangedListener { 26 27 private static final String YEAR = "year"; 28 private static final String MONTH = "month"; 29 private static final String DAY = "day"; 30 31 private final DatePicker mDatePicker; 32 private final DatePickerDialog.OnDateSetListener mCallBack; 33 private final Calendar mCalendar; 34 35 private boolean mTitleNeedsUpdate = true; 36 private Context mContext; 37 38 39 /** 40 * @param context 41 * The context the dialog is to run in. 42 * @param callBack 43 * How the parent is notified that the date is set. 44 * @param year 45 * The initial year of the dialog. 46 * @param monthOfYear 47 * The initial month of the dialog. 48 * @param dayOfMonth 49 * The initial day of the dialog. 50 */ 51 public MyDatePickerDialog(Context context, DatePickerDialog.OnDateSetListener callBack, 52 int year, int monthOfYear, int dayOfMonth) { 53 this(context, 0, callBack, year, monthOfYear, dayOfMonth); 54 this.mContext = context; 55 } 56 57 /** 58 * @param context 59 * The context the dialog is to run in. 60 * @param theme 61 * the theme to apply to this dialog 62 * @param callBack 63 * How the parent is notified that the date is set. 64 * @param year 65 * The initial year of the dialog. 66 * @param monthOfYear 67 * The initial month of the dialog. 68 * @param dayOfMonth 69 * The initial day of the dialog. 70 */ 71 public MyDatePickerDialog(Context context, int theme, 72 DatePickerDialog.OnDateSetListener callBack, int year, int monthOfYear, 73 int dayOfMonth) { 74 super(context, theme); 75 76 this.mContext = context; 77 78 mCallBack = callBack; 79 80 mCalendar = Calendar.getInstance(); 81 82 Context themeContext = getContext(); 83 setButton(BUTTON_POSITIVE, 84 themeContext.getText(R.string.OK), this); 85 setIcon(0); 86 87 LayoutInflater inflater = (LayoutInflater) themeContext 88 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 89 View view = inflater.inflate(R.layout.date_picker_dialog, null); 90 setView(view); 91 mDatePicker = (DatePicker) view.findViewById(R.id.datePicker); 92 mDatePicker.init(year, monthOfYear, dayOfMonth, this); 93 updateTitle(year, monthOfYear, dayOfMonth); 94 } 95 96 public void onClick(DialogInterface dialog, int which) { 97 tryNotifyDateSet(); 98 } 99 100 public void onDateChanged(DatePicker view, int year, int month, int day) { 101 mDatePicker.init(year, month, day, this); 102 updateTitle(year, month, day); 103 } 104 105 /** 106 * Gets the {@link DatePicker} contained in this dialog. 107 * 108 * @return The calendar view. 109 */ 110 public DatePicker getDatePicker() { 111 return mDatePicker; 112 } 113 114 /** 115 * Sets the current date. 116 * 117 * @param year 118 * The date year. 119 * @param monthOfYear 120 * The date month. 121 * @param dayOfMonth 122 * The date day of month. 123 */ 124 public void updateDate(int year, int monthOfYear, int dayOfMonth) { 125 mDatePicker.updateDate(year, monthOfYear, dayOfMonth); 126 } 127 128 private void tryNotifyDateSet() { 129 if (mCallBack != null) { 130 mDatePicker.clearFocus(); 131 mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), 132 mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); 133 } 134 } 135 136 @Override 137 protected void onStop() { 138 tryNotifyDateSet(); 139 super.onStop(); 140 } 141 142 @SuppressLint("NewApi") 143 private void updateTitle(int year, int month, int day) { 144 if (!mDatePicker.getCalendarViewShown()) { 145 mCalendar.set(Calendar.YEAR, year); 146 mCalendar.set(Calendar.MONTH, month); 147 mCalendar.set(Calendar.DAY_OF_MONTH, day); 148 String title = DateUtils.formatDateTime(mContext, 149 mCalendar.getTimeInMillis(), DateUtils.FORMAT_SHOW_DATE 150 | DateUtils.FORMAT_SHOW_WEEKDAY 151 | DateUtils.FORMAT_SHOW_YEAR 152 | DateUtils.FORMAT_ABBREV_MONTH 153 | DateUtils.FORMAT_ABBREV_WEEKDAY); 154 setTitle(title); 155 mTitleNeedsUpdate = true; 156 } else { 157 if (mTitleNeedsUpdate) { 158 mTitleNeedsUpdate = false; 159 setTitle(R.string.Date); 160 } 161 } 162 } 163 164 @Override 165 public Bundle onSaveInstanceState() { 166 Bundle state = super.onSaveInstanceState(); 167 state.putInt(YEAR, mDatePicker.getYear()); 168 state.putInt(MONTH, mDatePicker.getMonth()); 169 state.putInt(DAY, mDatePicker.getDayOfMonth()); 170 return state; 171 } 172 173 @Override 174 public void onRestoreInstanceState(Bundle savedInstanceState) { 175 super.onRestoreInstanceState(savedInstanceState); 176 int year = savedInstanceState.getInt(YEAR); 177 int month = savedInstanceState.getInt(MONTH); 178 int day = savedInstanceState.getInt(DAY); 179 mDatePicker.init(year, month, day, this); 180 } 181 }
如果需要自定義樣式,可以自己設定style.xml 和layout.xml就可以