我们一般会直接使用android提供的系统对话框,但有时候需要自己定义对话框样式,普通对话框还好,但是日期选择对话框中的日期选择部分十分复杂,为了一点样式的修改就去自定义View的话又得不偿失,这时通过套样系统源码来实现自己需要的样式就能很方便的实现我们的需求。
下面的代码只是对DatePickerDialog源码稍加修改,只做演示,原理很简单,大家举一反三就可以自由定义需要的样式了。
套用DatePickerDialog源码实现的自定义日期选择器类:
//主要代码copy自DatePickerDialog源码
public class DatePickerView extends AlertDialog implements
OnDateChangedListener {
private static final String YEAR = "year";
private static final String MONTH = "month";
private static final String DAY = "day";
private final DatePicker mDatePicker;
private final OnDateSetListener mCallBack;
private View view;
/**
* The callback used to indicate the user is done filling in the date.
*/
public interface OnDateSetListener {
void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth);
}
public DatePickerView(Context context, OnDateSetListener callBack,
int year, int monthOfYear, int dayOfMonth) {
this(context, 0, callBack, year, monthOfYear, dayOfMonth);
}
public DatePickerView(Context context, int theme,
OnDateSetListener callBack, int year, int monthOfYear,
int dayOfMonth) {
super(context, theme);
mCallBack = callBack;
Context themeContext = getContext();
//將設置alertdialog的settitle和setButton方法注释掉,因为下面要使用setContentView(View view)方法
//代替原有的setView(View view)方法,区别是替换的范围不同。替换后就不需要设置alertdialog的title和button了。
// setButton(BUTTON_POSITIVE,
// themeContext.getText(R.string.date_time_set), this);
// setButton(BUTTON_NEGATIVE, themeContext.getText(R.string.cancel),
// (OnClickListener) null);
// setIcon(0);
// setTitle(R.string.date_picker_dialog_title);
LayoutInflater inflater = (LayoutInflater) themeContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//注意,其实datepickerdialog就是把系统提供的日期选择器DatePicker包装一下而已,所以只需要实现自己需要的布局样式
//然后把DatePicker嵌套进去就可以了。
view = inflater.inflate(R.layout.date_picker_dialog, null);
view.setBackgroundColor(Color.BLUE);
// setView(view);
mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
mDatePicker.init(year, monthOfYear, dayOfMonth, this);
//实现自己的标题和ok按钮
setTitle("选择日期:");
setButton();
}
public void myShow() {
//自己实现show方法,主要是为了把setContentView方法放到show方法后面,否则会报错。
show();
setContentView(view);
}
private void setTitle(String title) {
//获取自己定义的title布局并赋值。
((TextView) view.findViewById(R.id.date_picker_title)).setText(title);
}
private void setButton() {
//获取自己定义的响应按钮并设置监听,直接调用构造时传进来的CallBack接口(为了省劲,没有自己写接口,直接用之前本类定义好的)同时关闭对话框。
view.findViewById(R.id.date_picker_ok).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mCallBack != null) {
mDatePicker.clearFocus();
mCallBack.onDateSet(mDatePicker,
mDatePicker.getYear(),
mDatePicker.getMonth(),
mDatePicker.getDayOfMonth());
}
dismiss();
}
});
}
public void onDateChanged(DatePicker view, int year, int month, int day) {
mDatePicker.init(year, month, day, null);
}
/**
* Gets the {@link DatePicker} contained in this dialog.
*
* @return The calendar view.
*/
public DatePicker getDatePicker() {
return mDatePicker;
}
public void updateDate(int year, int monthOfYear, int dayOfMonth) {
mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt(YEAR, mDatePicker.getYear());
state.putInt(MONTH, mDatePicker.getMonth());
state.putInt(DAY, mDatePicker.getDayOfMonth());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
int year = savedInstanceState.getInt(YEAR);
int month = savedInstanceState.getInt(MONTH);
int day = savedInstanceState.getInt(DAY);
mDatePicker.init(year, month, day, this);
}
}
布局文件:date_picker_dialog
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/date_picker_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:textColor="#FFFFFF" />
<DatePicker
android:id="@+id/datePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:calendarViewShown="false"
android:spinnersShown="true" />
<TextView
android:id="@+id/date_picker_ok"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:text="OK"
android:textColor="#FFFFFF" />
</LinearLayout>
调用方法:
DatePickerView datePickerView = new DatePickerView(this,
new DatePickerView.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
Toast.makeText(
MainActivity.this,
year + "-" + monthOfYear + 1 + "-" + dayOfMonth,
Toast.LENGTH_SHORT).show();
}
}, 2013, 11, 18);
datePickerView.myShow();