程序员人生 网站导航

自定义时间选择器

栏目:综合技术时间:2016-09-28 10:12:46

前言

最近写了1个关于快餐送餐时间的AlertDialog程序,现在想分享给大家,如有甚么不公道的地方望提出。

效果图

效果图

使用方法

//只需要new出来然后show()就能够使用了 new SendTimePickerDialog(this, new SendTimePickerDialog.OnReturnDateListener() { @Override public void onReturnDate(int date, int hour, int minute) { //选择后返回的数据 String dateStr = SendTimePicker.dateToString(date); //把时间转化为 今天 或 明天 Log.d("MainActivity",dateStr + " "+hour+" "+ minute); } }).show();

实现原理

实现的原理是模仿DatePickerDialog继承AlertDialog以下图

DatePickerDialog

实现之前我们必须先自定义1个主布局,然后把主布局加到AlertDialog中,就如DatePickerDialog的实现1样,我先把整体软件的代码结构贴出来

这里写图片描述

所以我打算先讲怎样实现时间选择的主布局,然后再讲怎样把主布局加到AlertDialog中

1、自定义时间选择的布局

我的方法是使用3个NumberPicker组成1个选择器
xml代码以下

<?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <NumberPicker android:id="@+id/datePicker" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <NumberPicker android:id="@+id/hourPicker" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp"/> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text=":" android:textSize="30sp" /> <NumberPicker android:id="@+id/minutePicker" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
效果以下,样式不1样是由于设置的安卓版本,不过终究都能实现选择时间的需求。

这里写图片描述

然后我们现在就能够写SendTimePicker类了,这个类只是提供对外读取时间的接口和显示布局,代码以下
package com.sven.my.test.custom.view; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; import android.widget.NumberPicker; import com.sven.my.test.R; import java.util.Calendar; public class SendTimePicker extends FrameLayout { /** * 时间标志 */ public static final int TODAY_FLAG = 0x0; public static final int TOMORROW_FLAG = 0x1; private static final String TODAY = "今天"; private static final String TOMORROW = "明天"; /** * 布局里的3个数字选择器 */ private NumberPicker mDatePicker; private NumberPicker mHourPicker; private NumberPicker mMinutePicker; private int mDate; private int mHour; private int mMinute; Calendar mCalendar; private String[] mDates = new String[]{ TODAY ,TOMORROW }; /** * 选择改变时的回调接口 */ private OnSelectChangedListener mOnSelectChangedListener; public SendTimePicker(Context context) { this(context,null); } public SendTimePicker(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SendTimePicker(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //初始化时间 mCalendar = Calendar.getInstance(); //获得系统时间 mHour = mCalendar.get(Calendar.HOUR_OF_DAY); mMinute = mCalendar.get(Calendar.MINUTE); mDate = TODAY_FLAG; //默许为今天 //初始化布局 View mainView = LayoutInflater.from(context).inflate(R.layout.send_time_picker,null); mDatePicker = (NumberPicker) mainView.findViewById(R.id.datePicker); mHourPicker = (NumberPicker) mainView.findViewById(R.id.hourPicker); mMinutePicker = (NumberPicker) mainView.findViewById(R.id.minutePicker); //设置3个选择器的数值 mDatePicker.setDisplayedValues(mDates); loadPicker(mDatePicker, 0, mDates.length - 1, 0); loadPicker(mHourPicker, mHour,23, mHour); loadPicker(mMinutePicker, mMinute,59, mMinute); //添加到布局中 addView(mainView); //设置监听 initListener(); } /** * 加载选择框 */ private void loadPicker(NumberPicker numberPicker, int minValue, int maxValue, int value){ numberPicker.setMinValue(minValue); numberPicker.setMaxValue(maxValue); numberPicker.setValue(value); } /** * 设置监听 */ private void initListener() { mDatePicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { //为了让用户不能选择今天之前的时间 mDate = newVal; int currentHour = mCalendar.get(Calendar.HOUR_OF_DAY); int currentMinute = mCalendar.get(Calendar.MINUTE); if(mHour < currentHour) mHour = currentHour; if(mMinute < currentMinute) mMinute = currentMinute; if(mDate == TODAY_FLAG){ loadPicker(mHourPicker,currentHour,23,mHour); loadPicker(mMinutePicker,currentMinute,59,mMinute); }else if(mDate == TOMORROW_FLAG){ loadPicker(mHourPicker,0,23,mHour); loadPicker(mMinutePicker,0,59,mMinute); } callOnSelectListener(); } }); mHourPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mHour = newVal; callOnSelectListener(); } }); mMinutePicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mMinute = newVal; callOnSelectListener(); } }); } /** * 把时间转化为可视的 */ public static String dateToString(int date){ return date==TODAY_FLAG ? TODAY : TOMORROW; } /** * 调用改变选择的回调接口 */ private void callOnSelectListener(){ if(mOnSelectChangedListener != null){ mOnSelectChangedListener.onSelectChanged(mDate, mHour, mMinute); } } public void setOnSelectChangedListener(OnSelectChangedListener mOnSelectChangedListener) { this.mOnSelectChangedListener = mOnSelectChangedListener; } /** * 选择产生改变的回调接口 */ public interface OnSelectChangedListener{ void onSelectChanged(int newDate, int newHour, int newMinute); } public void setDate(int date) { this.mDate = date; mDatePicker.setValue(date); } public void setHour(int hour) { this.mHour = hour; mHourPicker.setValue(hour); } public void setMinute(int minute) { this.mMinute = minute; mMinutePicker.setValue(minute); } public int getDate() { return mDate; } public int getHour() { return mHour; } public int getMinute() { return mMinute; } }
写完这个布局大家可以先试着用这个自定义控件运行下
<?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.sven.my.test.custom.view.SendTimePicker android:layout_width="wrap_content" android:layout_height="wrap_content"></com.sven.my.test.custom.view.SendTimePicker> </LinearLayout>

这里写图片描述

2、把自定义布局整合到AlertDialog中

我们只需要继承AlertDialog然后把刚刚那个自定义布局添加到AlertDialog中就能够了,以下图,剩下的显示之类的功能AlertDialog内部已帮我们实现了,所以不需要我们操心
setView(mSendTimePicker); //把选择器添加到提示框
下面贴上代码
package com.sven.my.test.custom.view; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; public class SendTimePickerDialog extends AlertDialog { /** * 回调接口 */ private OnReturnDateListener mOnReturnDateListener; /** * 选择器主布局 */ private SendTimePicker mSendTimePicker; public SendTimePickerDialog(Context context){ this(context,null); } public SendTimePickerDialog(Context context, final OnReturnDateListener onReturnDateListener) { super(context); //设置回调监听 mOnReturnDateListener = onReturnDateListener; //初始化布局 mSendTimePicker = new SendTimePicker(getContext()); setView(mSendTimePicker); //把选择器添加到提示框 //设置标题 setTimeTitle(); //设置标题 //设置监听 数值选择改变监听 mSendTimePicker.setOnSelectChangedListener(new SendTimePicker.OnSelectChangedListener() { @Override public void onSelectChanged(int newDate, int newHour, int newMinute) { setTimeTitle(SendTimePicker.dateToString(newDate) , newHour, newMinute); //设置标题 } }); //点击肯定的监听 setButton(AlertDialog.BUTTON_POSITIVE, "肯定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if(onReturnDateListener != null){ onReturnDateListener.onReturnDate(mSendTimePicker.getDate() ,mSendTimePicker.getHour(),mSendTimePicker.getMinute()); } } }); } /** * 设置标题 */ private void setTimeTitle(){ //获得时间 int date = mSendTimePicker.getDate(); int hour = mSendTimePicker.getHour(); int minute = mSendTimePicker.getMinute(); this.setTimeTitle(SendTimePicker.dateToString(date),hour,minute); } /** * 设置标题 */ private void setTimeTitle(String date, int hour, int minute){ String titleStr = String.format("%s %d:%d",date,hour,minute); setTitle(titleStr); } public void setOnReturnDateListener(OnReturnDateListener mOnReturnDateListener) { this.mOnReturnDateListener = mOnReturnDateListener; } /** * 返回数据的接口 */ public interface OnReturnDateListener{ void onReturnDate(int date, int hour, int minute); } }
然后我们就能够使用了,就跟前面写的1样
//只需要new出来然后show()就能够使用了 new SendTimePickerDialog(this, new SendTimePickerDialog.OnReturnDateListener() { @Override public void onReturnDate(int date, int hour, int minute) { //选择后返回的数据 String dateStr = SendTimePicker.dateToString(date); //把时间转化为 今天 或 明天 Log.d("MainActivity",dateStr + " "+hour+" "+ minute); } }).show();

总结

就此全部设计结束,思路是先设计1个时间选择器,然后再创建1个类继承AlertDialog,最后就是把自己设计的时间选择器设置进继承AlertDialog的类中。

下面是完全代码大家可以下载

下载地址

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐