自定义日期选择控件实现单个DatePicker选择起始和结束日期
应应用需求,一个日期选择控件要完成开始日期和结束日期的选择,并且结束日期未选择时,开始日期时可以更改的效果图如下:
自定义日期类
public class MyStyleDatePicker extends AlertDialog implements DialogInterface.OnClickListener, DatePicker.OnDateChangedListener, View.OnClickListener {
//初始化选择的日期
private static final String YEAR = "year";
private static final String MONTH = "month";
private static final String DAY = "day";
private DatePicker mDatePicker;
//定义初始化日期的接口
private final OnDateSetListener mCallBack;
//顶部的日期标题
private TextView tv_datatitle_start, tv_datatitle_end, tv_cancel, tv_queding;
private int isClickWanCount = 0;
private String StartData = "", EndData = "";
//记录每个起始时间 和结束时间
private boolean isClickStart, isClickEnd;
private Context mContext; //获取上下文
//日期变化时候调用
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
view.init(year, monthOfYear, dayOfMonth, this);
}
/**
* view的onclick
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_cancel:
dismiss();
break;
case R.id.tv_queding:
if (tv_queding.getText().toString().equals("下一步")) { //这是给起始日期赋值
tv_queding.setText("确定");
//给顶部textview的颜色进行更改
tv_datatitle_start.setTextColor(Color.BLACK);
tv_datatitle_start.setBackgroundColor(Color.parseColor("#F5F5F5"));
tv_datatitle_end.setTextColor(Color.WHITE);
tv_datatitle_end.setBackgroundColor(Color.parseColor("#0eb0f0"));
isClickStart = true;
tryNotifyDateSet(true);
//如果结束时间选取了
if (!EndData.equals("")) {
String[] dataArr = EndData.split("-");
updateStartDate(Integer.parseInt(dataArr[0]), Integer.parseInt(dataArr[1]), Integer.parseInt(dataArr[2]));
}
} else if (tv_queding.getText().toString().equals("确定")) { //给结束日期赋值
isClickEnd = true;
if (isClickStart && isClickEnd) { //两个都赋值了 点击确定的时候可以退出
isClickStart = false;
isClickEnd = false;
dismiss();
} else {
Toast.makeText(mContext, "起始日期尚未选择,请选择起始日期。", Toast.LENGTH_SHORT).show();
}
tryNotifyDateSet(false); //给结束时间赋值
}
break;
case R.id.tv_datatitle_start:
if (!StartData.equals("")) {
String[] dataArr = StartData.split("-");
updateStartDate(Integer.parseInt(dataArr[0]), Integer.parseInt(dataArr[1]), Integer.parseInt(dataArr[2]));
}
//点击开始时间
//给顶部textview的颜色进行更改
tv_datatitle_start.setTextColor(Color.WHITE);
tv_datatitle_start.setBackgroundColor(Color.parseColor("#0eb0f0"));
tv_datatitle_end.setTextColor(Color.BLACK);
tv_datatitle_end.setBackgroundColor(Color.parseColor("#F5F5F5"));
tv_cancel.setText("取消");
tv_queding.setText("下一步");
break;
case R.id.tv_datatitle_end:
if (!EndData.equals("")) {
String[] dataArr = EndData.split("-");
updateStartDate(Integer.parseInt(dataArr[0]), Integer.parseInt(dataArr[1]), Integer.parseInt(dataArr[2]));
}
//给顶部textview的颜色进行更改
tv_datatitle_start.setTextColor(Color.BLACK);
tv_datatitle_start.setBackgroundColor(Color.parseColor("#F5F5F5"));
tv_datatitle_end.setTextColor(Color.WHITE);
tv_datatitle_end.setBackgroundColor(Color.parseColor("#0eb0f0"));
tv_cancel.setText("取消");
tv_queding.setText("确定");
break;
}
}
//设置定义日期的接口 都是传入的年月日 和日期选择器 //新增boolean类型的 isStartData 是开始的日期
public interface OnDateSetListener {
void onDateSet(DatePicker mDatePicker, int startYear, int startMonthOfYear, int startDayOfMonth, boolean isStartData);
}
//三个构造函数
public MyStyleDatePicker(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
this(context, 0, callBack, year, monthOfYear, dayOfMonth);
}
public MyStyleDatePicker(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
this(context, 0, callBack, year, monthOfYear, dayOfMonth, true);
}
public MyStyleDatePicker(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean isDayVisible) {
super(context, theme);
//给传入的回调接口赋值
mCallBack = callBack;
//
Context themeContext = getContext();
mContext = themeContext;
// setButton(BUTTON_POSITIVE, "确 定", this);
// setButton(BUTTON_NEGATIVE, "取 消", this);
// setButton(BUTTON_POSITIVE,
// themeContext.getText(android.R.string.date_time_done), this);
setIcon(0);
LayoutInflater inflater = (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//将自定义的日期view填充成控件
View view = inflater.inflate(R.layout.my_style_date_picker_layout, null);
tv_datatitle_start = (TextView) view.findViewById(R.id.tv_datatitle_start);
tv_datatitle_end = (TextView) view.findViewById(R.id.tv_datatitle_end);
tv_cancel = (TextView) view.findViewById(R.id.tv_cancel);
tv_queding = (TextView) view.findViewById(R.id.tv_queding);
tv_cancel.setOnClickListener(this);
tv_queding.setOnClickListener(this);
tv_datatitle_start.setOnClickListener(this);
tv_datatitle_end.setOnClickListener(this);
setView(view);
//初始化日期控件
mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
//初始化日期控件中的值
mDatePicker.init(year, monthOfYear, dayOfMonth, this);
// updateTitle(year, monthOfYear, dayOfMonth);
// 如果要隐藏当前日期,则使用下面方法。 最后一个参数是控制是否隐藏日期的
if (!isDayVisible) {
hidDay(mDatePicker);
}
}
/**
* 设置按钮 显示
*/
public void setTitleName(String titleName) {
// dataTitle.setText(titleName);
}
/**
* 更新起始时间的方法
*/
public void setStartData(String startData) {
StartData = startData;
Log.d("flag", "------------------------------当前的起始时间为" + StartData);
}
/**
* 更新结束时间的方法
*/
public void setEndData(String endData) {
EndData = endData;
Log.d("flag", "------------------------------当前的结束时间为" + StartData);
}
/**
* 重点 输入指定的DatePicker 隐藏DatePicker中的日期显示
*/
private void hidDay(DatePicker mDatePicker) {
Field[] datePickerfFields = mDatePicker.getClass().getDeclaredFields();
for (Field datePickerField : datePickerfFields) {
if ("mDaySpinner".equals(datePickerField.getName())) {
datePickerField.setAccessible(true);
Object dayPicker = new Object();
try {
dayPicker = datePickerField.get(mDatePicker);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
// datePicker.getCalendarView().setVisibility(View.GONE);
((View) dayPicker).setVisibility(View.GONE);
}
}
}
/**
* 重写的点击对话框的接口
*/
@Override
public void onClick(DialogInterface dialog, int which) {
// 如果是“取 消”按钮,则返回,如果是“确 定”按钮,则往下执行
if (which == BUTTON_POSITIVE)
tryNotifyDateSet(false);
}
/**
* 获取日期控件
*/
public DatePicker getDatePicker() {
return mDatePicker;
}
/**
* 更新日期的方法
*/
public void updateStartDate(int year, int monthOfYear, int dayOfMonth) {
mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
}
/**
* 当设置日期的回调接口不为null时候 启动通知设置日期 isStartData{true是给起始日期赋值 false是给结束日期赋值}
*/
private void tryNotifyDateSet(boolean isStartData) {
if (mCallBack != null) {
mDatePicker.clearFocus(); //回调接口设置日期要取消选择器的焦点
mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth(), isStartData);
}
}
@Override
protected void onStop() {
// tryNotifyDateSet();
super.onStop();
}
//保留当前的状态
@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);
}
}
布局代码:
<?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:gravity="center_horizontal"
android:paddingTop="10dp"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="5dip">
<LinearLayout
android:id="@+id/ll_top_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_datatitle_start"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:text="开始日期"
android:gravity="center"
android:textColor="@color/lightBg"
android:background="@color/yyt_background"
/>
<TextView
android:id="@+id/tv_datatitle_end"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
android:text="结束日期"/>
</LinearLayout>
<DatePicker
android:spinnersShown="true"
android:id="@+id/datePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:calendarViewShown="false"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="取消"
android:gravity="center"
/>
<TextView
android:id="@+id/tv_queding"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="下一步"
android:gravity="center"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
使用:
// 最后一个false表示不显示日期,如果要显示日期,最后参数可以是true或者不用输入
dd = new MyStyleDatePicker(WorkInstructionAddActivity.this, 0, new MyStyleDatePicker.OnDateSetListener() {
@Override
public void onDateSet(DatePicker mDatePicker, int startYear, int startMonthOfYear, int startDayOfMonth, boolean isStartData) {
//选择完后将年和月设置上去
String mo = "";
String ri = "";
if (startMonthOfYear <= 9) {
mo = "0" + (startMonthOfYear + 1 + "") + "";
} else {
mo = startMonthOfYear + 1 + "";
}
if (startDayOfMonth <= 9) {
ri = "0" + (startDayOfMonth + "");
} else {
ri = startDayOfMonth + "";
}
if (isStartData) { //判断传过来的是起始日期
startData = startYear + "-" + mo + "-" + ri;
MyLogUtil.d(WorkInstructionAddActivity.class, "-----------时间控件----startData--" + startData + "---endData---" + endData);
dd.setStartData(startYear + "-" + startMonthOfYear + "-" + startDayOfMonth); //将选择的起始日期传过去
} else {
endData = startYear + "-" + mo + "-" + ri;
dd.setEndData(startYear + "-" + startMonthOfYear + "-" + startDayOfMonth);
MyLogUtil.d(WorkInstructionAddActivity.class, "-----------时间控件----startData--" + startData + "---endData---" + endData);
//对比时间 加提醒
if (DateUtils.isChao(startData, endData) || startData.equals(endData)) { //说明时间正常
tv_agent.setText(startData + " - " + endData);
} else {
tv_agent.setText(endData + " - " + startData);
}
}
}
}, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));