github上面有这个包,网址: https://github.com/mrfluency/Time-Selector
但是我在使用时候发现不能设置当前时间,所以我这里简单封装了一下。
目前增加的新的功能是:可以直接传入textview控件,时间选择器会直接设置好这个textview控件上面的时间,当选择好时间后,点击确定时间自动显示在传入的这个textview控件上面。
废话不多说,为了满足一些人不想依赖包,就行考屁几个文件就能用这个控件的意愿,我这里就把需要的所有的文件列出来。你需要改的只有包名。
第一个:DateUtils
package top.chinapeople.timeselector.time_selector_current;import java.text.SimpleDateFormat;import java.util.Date; /** * Author: wangsz * Time: created at 2016/7/7. */ public class DateUtils { public static final String DEFAULT_TEMPLATE_DAY = "yyyy-MM-dd"; public static final String DEFAULT_TEMPLATE = "yyyy-MM-dd HH:mm:ss"; private DateUtils(){} /** *-日期控件 * * / /** * 使用用户格式提取字符串日期 * * @param strDate 日期字符串 * @param pattern 日期格式 * @return */ public static Date parse(String strDate, String pattern) { if (TextUtil.isEmpty(strDate)) { return null; } try { SimpleDateFormat df = new SimpleDateFormat(pattern); return df.parse(strDate); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 使用用户格式格式化日期 * * @param date 日期 * @param pattern 日期格式 * @return */ public static String format(Date date, String pattern) { String returnValue = ""; if (date != null) { SimpleDateFormat df = new SimpleDateFormat(pattern); returnValue = df.format(date); } return (returnValue); } }
第二个:ScreenUtil
package top.chinapeople.timeselector.time_selector_current;import android.content.Context;import android.util.DisplayMetrics;import android.view.WindowManager; /** * 日期picker相关 * Created by wangsz on 2016/8/30. */ public class ScreenUtil { public static int height; public static int width; private Context context; private static ScreenUtil instance; private ScreenUtil(Context context) { this.context = context; WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(dm); width = dm.widthPixels; height = dm.heightPixels; } public static ScreenUtil getInstance(Context context) { if (instance == null) { instance = new ScreenUtil(context); } return instance; } /** * 得到手机屏幕的宽度, pix单位 */ public int getScreenWidth() { return width; } }
第三个:TextUtil
package top.chinapeople.timeselector.time_selector_current;import java.text.DecimalFormat; /** * 日期picker相关 * Created by wangsz on 2016/8/30. */ public class TextUtil { private TextUtil(){} public static boolean isEmpty(String str) { if (str == null || "".equals(str) || "null".equalsIgnoreCase(str)) { return true; } for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); if (c != ' ' && c != '\t' && c != '\r' && c != '\n') { return false; } } return true; } public static String filterNull(String str, String _default, String tail){ if (str == null || "".equals(str) || "null".equalsIgnoreCase(str)) { return _default; }else { if(tail != null) { str += tail; } return str; } } //重载 public static String filterNull(String str, String _default){ return filterNull(str, _default, null); } //重载 public static String filterNull(String str){ return filterNull(str, "", null); } //重载 public static String filterNull(Float f, String _default, String tail){ String str = f+""; if (str == null || "".equals(str) || "null".equalsIgnoreCase(str)) { return _default; }else { if(tail != null) { str += tail; } return str; } } /** * 保留2位小数 * @return */ public String fix(float f) { DecimalFormat df = new DecimalFormat("#.00"); return df.format(f); } }
第四个:PickerView
package top.chinapeople.timeselector.time_selector_current;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Align;import android.graphics.Paint.FontMetricsInt;import android.graphics.Paint.Style;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import java.util.ArrayList;import java.util.List;import java.util.Timer;import java.util.TimerTask; /** * 日期picker相关 * Created by wangsz on 2016/8/30. */ public class PickerView extends View { public static final String TAG = "PickerView"; /** * text之间间距和minTextSize之比 */ public static final float MARGIN_ALPHA = 2.8f; /** * 自动回滚到中间的速度 */ public static final float SPEED = 2; private List<String> mDataList; /** * 选中的位置,这个位置是mDataList的中心位置,一直不变 */ private int mCurrentSelected; private Paint mPaint, nPaint; private float mMaxTextSize = 80; private float mMinTextSize = 40; private float mMaxTextAlpha = 255; private float mMinTextAlpha = 120; private int mColorText = 0x333333; private int nColorText = 0x666666; private int mViewHeight; private int mViewWidth; private float mLastDownY; /** * 滑动的距离 */ private float mMoveLen = 0; private boolean isInit = false; private on SelectListener mSelectListener; private Timer timer; private MyTimerTask mTask; Handler updateHandler = new Handler() { @Override public void handleMessage(Message msg) { if (Math.abs(mMoveLen) < SPEED) { mMoveLen = 0; if (mTask != null) { mTask.cancel(); mTask = null; performSelect(); } } else // 这里mMoveLen / Math.abs(mMoveLen)是为了保有mMoveLen的正负号,以实现上滚或下滚 mMoveLen = mMoveLen - mMoveLen / Math.abs(mMoveLen) * SPEED; invalidate(); } }; private boolean canScroll = true; public PickerView(Context context) { super(context); init(); } public PickerView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public void seton SelectListener(on SelectListener listener) { mSelectListener = listener; } private void performSelect() { if (mSelectListener != null) mSelectListener.on Select(mDataList.get(mCurrentSelected)); } public void setData(List<String> datas) { mDataList = datas; mCurrentSelected = datas.size() / 4; invalidate(); } /** * 选择选中的item的index * * @param selected */ public void setSelected(int selected) { mCurrentSelected = selected; int distance = mDataList.size() / 2 - mCurrentSelected; if (distance < 0) for (int i = 0; i < -distance; i++) { moveHeadToTail(); mCurrentSelected--; } else if (distance > 0) for (int i = 0; i < distance; i++) { moveTailToHead(); mCurrentSelected++; } invalidate(); } /** * 选择选中的内容 * * @param mSelectItem */ public void setSelected(String mSelectItem) { for (int i = 0; i < mDataList.size(); i++) if (mDataList.get(i).equals(mSelectItem)) { setSelected(i); break; } } private void moveHeadToTail() { String head = mDataList.get(0); mDataList.remove(0); mDataList.add(head); } private void moveTailToHead() { String tail = mDataList.get(mDataList.size() - 1); mDataList.remove(mDataList.size() - 1); mDataList.add(0, tail); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mViewHeight = getMeasuredHeight(); mViewWidth = getMeasuredWidth(); // 按照View的高度计算字体大小 mMaxTextSize = mViewHeight / 7f; mMinTextSize = mMaxTextSize / 2.2f; isInit = true; invalidate(); } private void init() { timer = new Timer(); mDataList = new ArrayList<String>(); //第一个paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Style.FILL); mPaint.setTextAlign(Align.CENTER); mPaint.setColor(getResources().getColor(R.color.colorPrimary)); //第二个paint nPaint = new Paint(Paint.ANTI_ALIAS_FLAG); nPaint.setStyle(Style.FILL); nPaint.setTextAlign(Align.CENTER); nPaint.setColor(mColorText); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 根据index绘制view if (isInit) drawData(canvas); } private void drawData(Canvas canvas) { // 先绘制选中的text再往上往下绘制其余的text float scale = parabola(mViewHeight / 4.0f, mMoveLen); float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize; mPaint.setTextSize(size); mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha)); // text居中绘制,注意baseline的计算才能达到居中,y值是text中心坐标 float x = (float) (mViewWidth / 2.0); float y = (float) (mViewHeight / 2.0 + mMoveLen); FontMetricsInt fmi = mPaint.getFontMetricsInt(); float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0)); canvas.drawText(mDataList.get(mCurrentSelected), x, baseline, mPaint); // 绘制上方data for (int i = 1; (mCurrentSelected - i) >= 0; i++) { drawOtherText(canvas, i, -1); } // 绘制下方data for (int i = 1; (mCurrentSelected + i) < mDataList.size(); i++) { drawOtherText(canvas, i, 1); } } /** * @param canvas * @param position 距离mCurrentSelected的差值 * @param type 1表示向下绘制,-1表示向上绘制 */ private void drawOtherText(Canvas canvas, int position, int type) { float d = MARGIN_ALPHA * mMinTextSize * position + type * mMoveLen; float scale = parabola(mViewHeight / 4.0f, d); float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize; nPaint.setTextSize(size); nPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha)); float y = (float) (mViewHeight / 2.0 + type * d); FontMetricsInt fmi = nPaint.getFontMetricsInt(); float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0)); canvas.drawText(mDataList.get(mCurrentSelected + type * position), (float) (mViewWidth / 2.0), baseline, nPaint); } /** * 抛物线 * * @param zero 零点坐标 * @param x 偏移量 * @return scale */ private float parabola(float zero, float x) { float f = (float) (1 - Math.pow(x / zero, 2)); return f < 0 ? 0 : f; } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: doDown(event); break; case MotionEvent.ACTION_MOVE: doMove(event); break; case MotionEvent.ACTION_UP: doUp(event); break; } return true; } private void doDown(MotionEvent event) { if (mTask != null) { mTask.cancel(); mTask = null; } mLastDownY = event.getY(); } private void doMove(MotionEvent event) { mMoveLen += (event.getY() - mLastDownY); if (mMoveLen > MARGIN_ALPHA * mMinTextSize / 2) { // 往下滑超过离开距离 moveTailToHead(); mMoveLen = mMoveLen - MARGIN_ALPHA * mMinTextSize; } else if (mMoveLen < -MARGIN_ALPHA * mMinTextSize / 2) { // 往上滑超过离开距离 moveHeadToTail(); mMoveLen = mMoveLen + MARGIN_ALPHA * mMinTextSize; } mLastDownY = event.getY(); invalidate(); } private void doUp(MotionEvent event) { // 抬起手后mCurrentSelected的位置由当前位置move到中间选中位置 if (Math.abs(mMoveLen) < 0.0001) { mMoveLen = 0; return; } if (mTask != null) { mTask.cancel(); mTask = null; } mTask = new MyTimerTask(updateHandler); timer.schedule(mTask, 0, 10); } class MyTimerTask extends TimerTask { Handler handler; public MyTimerTask(Handler handler) { this.handler = handler; } @Override public void run() { handler.sendMessage(handler.obtainMessage()); } } public interface on SelectListener { void on Select(String text); } public void setCanScroll(boolean canScroll) { this.canScroll = canScroll; } @Override public boolean dispatchTouchEvent(MotionEvent event) { if (canScroll) return super.dispatchTouchEvent(event); else return false; } }
第五个:TimeSelector
package top.chinapeople.timeselector.time_selector_current;import android.animation.ObjectAnimator;import android.animation.PropertyValuesHolder;import android.app.Dialog;import android.content.Context;import android.view.Gravity;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.Calendar; /** * 日期picker相关 * Created by wangsz on 2016/8/30. */ public class TimeSelector { public interface ResultHandler { void handle(String time); } public enum SCROLLTYPE { YEAR(1), MONTH(2), DAY(4), HOUR(8), MINUTE(16); SCROLLTYPE(int value) { this.value = value; } public int value; } private int scrollUnits = SCROLLTYPE.YEAR.value + SCROLLTYPE.MONTH.value + SCROLLTYPE.DAY.value + SCROLLTYPE.HOUR.value + SCROLLTYPE.MINUTE.value; private ResultHandler handler; private Context context; private final String FORMAT_STR = "yyyy-MM-dd HH:mm"; private Dialog seletorDialog; private PickerView year_pv; private PickerView month_pv; private PickerView day_pv; private PickerView hour_pv; private PickerView minute_pv; private final int MAXMINUTE = 59; private int MAXHOUR = 23; private final int MINMINUTE = 0; private int MINHOUR = 0; private final int MAXMONTH = 12; private int curYear; private int curMonth; private int curDay; private int curHour; private int curMininute; private TextView tvDate; private ArrayList<String> year, month, day, hour, minute; private int startYear, startMonth, startDay, startHour, startMininute, endYear, endMonth, endDay, endHour, endMininute, minute_workStart, minute_workEnd, hour_workStart, hour_workEnd; private boolean spanYear, spanMon, spanDay, spanHour, spanMin; private Calendar selectedCalender = Calendar.getInstance(); private final long ANIMATORDELAY = 200L; private final long CHANGEDELAY = 90L; private String workStart_str; private String workEnd_str; private Calendar startCalendar; private Calendar curCalendar; private Calendar endCalendar; private TextView tv_cancle; private TextView tv_select; /** * @param context * @param resultHandler 选取时间后回调 * @param startDate format:"yyyy-MM-dd HH:mm" * @param endDate */ public TimeSelector(Context context, ResultHandler resultHandler, String startDate, String endDate) { this.context = context; this.handler = resultHandler; startCalendar = Calendar.getInstance(); endCalendar = Calendar.getInstance(); startCalendar.setTime(DateUtils.parse(startDate, FORMAT_STR)); endCalendar.setTime(DateUtils.parse(endDate, FORMAT_STR)); initDialog(); initView(); } /** * @param context * @param startDate * @param endDate * @param workStartTime 工作日起始时间 如:朝九晚五 format:"09:00" * @param workEndTime 工作日结束时间 format:"17:00" */ public TimeSelector(Context context, ResultHandler resultHandler, String startDate, String endDate, String workStartTime, String workEndTime) { /*this(context, resultHandler, startDate, endDate);*/ this.workStart_str = workStartTime; this.workEnd_str = workEndTime; } public void show(final TextView tvDate) { if (startCalendar.getTime().getTime() >= endCalendar.getTime().getTime()) { Toast.makeText(context, "起始时间应小于结束时间", Toast.LENGTH_LONG).show(); return; } this.tvDate = tvDate; curCalendar = Calendar.getInstance(); curCalendar.setTime(DateUtils.parse(tvDate.getText().toString(), FORMAT_STR)); if (!excuteWorkTime()) return; initParameter(); initTimer(); addListener(); tv_select.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { tvDate.setText(DateUtils.format(selectedCalender.getTime(), FORMAT_STR)); seletorDialog.dismiss(); } }); seletorDialog.show(); } private void initDialog() { if (seletorDialog == null) { seletorDialog = new Dialog(context, R.style.time_dialog); seletorDialog.setCancelable(false); seletorDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); seletorDialog.setContentView(R.layout.datetime_dialog_selector); Window window = seletorDialog.getWindow(); window.setGravity(Gravity.BOTTOM); WindowManager.LayoutParams lp = window.getAttributes(); int width = ScreenUtil.getInstance(context).getScreenWidth(); lp.width = width; window.setAttributes(lp); } } private void initView() { year_pv = (PickerView) seletorDialog.findViewById(R.id.year_pv); month_pv = (PickerView) seletorDialog.findViewById(R.id.month_pv); day_pv = (PickerView) seletorDialog.findViewById(R.id.day_pv); hour_pv = (PickerView) seletorDialog.findViewById(R.id.hour_pv); minute_pv = (PickerView) seletorDialog.findViewById(R.id.minute_pv); tv_cancle = (TextView) seletorDialog.findViewById(R.id.tv_cancle); tv_select = (TextView) seletorDialog.findViewById(R.id.tv_select); tv_cancle.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { seletorDialog.dismiss(); } }); } private void initParameter() { curYear = curCalendar.get(Calendar.YEAR); curMonth = curCalendar.get(Calendar.MONTH) + 1; curDay = curCalendar.get(Calendar.DAY_OF_MONTH); curHour = curCalendar.get(Calendar.HOUR_OF_DAY); curMininute = curCalendar.get(Calendar.MINUTE); startYear = startCalendar.get(Calendar.YEAR); startMonth = startCalendar.get(Calendar.MONTH) + 1; startDay = startCalendar.get(Calendar.DAY_OF_MONTH); startHour = startCalendar.get(Calendar.HOUR_OF_DAY); startMininute = startCalendar.get(Calendar.MINUTE); endYear = endCalendar.get(Calendar.YEAR); endMonth = endCalendar.get(Calendar.MONTH) + 1; endDay = endCalendar.get(Calendar.DAY_OF_MONTH); endHour = endCalendar.get(Calendar.HOUR_OF_DAY); endMininute = endCalendar.get(Calendar.MINUTE); spanYear = startYear != endYear; spanMon = (!spanYear) && (startMonth != endMonth); spanDay = (!spanMon) && (startDay != endDay); spanHour = (!spanDay) && (startHour != endHour); spanMin = (!spanHour) && (startMininute != endMininute); selectedCalender.setTime(curCalendar.getTime()); } private void initTimer() { initArrayList(); if (spanYear) { for (int i = startYear; i <= endYear; i++) { year.add(String.valueOf(i)); } for (int i = startMonth; i <= MAXMONTH; i++) { month.add(fomatTimeUnit(i)); } for (int i = startDay; i <= startCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); i++) { day.add(fomatTimeUnit(i)); } for (int i = startHour; i <= MAXHOUR; i++) { hour.add(fomatTimeUnit(i)); } for (int i = startMininute; i <= MAXMINUTE; i++) { minute.add(fomatTimeUnit(i)); } } else if (spanMon) { year.add(String.valueOf(startYear)); for (int i = startMonth; i <= endMonth; i++) { month.add(fomatTimeUnit(i)); } for (int i = startDay; i <= startCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); i++) { day.add(fomatTimeUnit(i)); } for (int i = startHour; i <= MAXHOUR; i++) { hour.add(fomatTimeUnit(i)); } for (int i = startMininute; i <= MAXMINUTE; i++) { minute.add(fomatTimeUnit(i)); } } else if (spanDay) { year.add(String.valueOf(startYear)); month.add(fomatTimeUnit(startMonth)); for (int i = startDay; i <= endDay; i++) { day.add(fomatTimeUnit(i)); } for (int i = startHour; i <= MAXHOUR; i++) { hour.add(fomatTimeUnit(i)); } for (int i = startMininute; i <= MAXMINUTE; i++) { minute.add(fomatTimeUnit(i)); } } else if (spanHour) { year.add(String.valueOf(startYear)); month.add(fomatTimeUnit(startMonth)); day.add(fomatTimeUnit(startDay)); for (int i = startHour; i <= endHour; i++) { hour.add(fomatTimeUnit(i)); } for (int i = startMininute; i <= MAXMINUTE; i++) { minute.add(fomatTimeUnit(i)); } } else if (spanMin) { year.add(String.valueOf(startYear)); month.add(fomatTimeUnit(startMonth)); day.add(fomatTimeUnit(startDay)); hour.add(fomatTimeUnit(startHour)); for (int i = startMininute; i <= endMininute; i++) { minute.add(fomatTimeUnit(i)); } } loadComponent(); } private boolean excuteWorkTime() { boolean res = true; if (!TextUtil.isEmpty(workStart_str) && !TextUtil.isEmpty(workEnd_str)) { String[] start = workStart_str.split(":"); String[] end = workEnd_str.split(":"); hour_workStart = Integer.parseInt(start[0]); minute_workStart = Integer.parseInt(start[1]); hour_workEnd = Integer.parseInt(end[0]); minute_workEnd = Integer.parseInt(end[1]); Calendar workStartCalendar = Calendar.getInstance(); Calendar workEndCalendar = Calendar.getInstance(); workStartCalendar.setTime(startCalendar.getTime()); workEndCalendar.setTime(endCalendar.getTime()); workStartCalendar.set(Calendar.HOUR_OF_DAY, hour_workStart); workStartCalendar.set(Calendar.MINUTE, minute_workStart); workEndCalendar.set(Calendar.HOUR_OF_DAY, hour_workEnd); workEndCalendar.set(Calendar.MINUTE, minute_workEnd); Calendar startTime = Calendar.getInstance(); Calendar endTime = Calendar.getInstance(); Calendar startWorkTime = Calendar.getInstance(); Calendar endWorkTime = Calendar.getInstance(); startTime.set(Calendar.HOUR_OF_DAY, startCalendar.get(Calendar.HOUR_OF_DAY)); startTime.set(Calendar.MINUTE, startCalendar.get(Calendar.MINUTE)); endTime.set(Calendar.HOUR_OF_DAY, endCalendar.get(Calendar.HOUR_OF_DAY)); endTime.set(Calendar.MINUTE, endCalendar.get(Calendar.MINUTE)); startWorkTime.set(Calendar.HOUR_OF_DAY, workStartCalendar.get(Calendar.HOUR_OF_DAY)); startWorkTime.set(Calendar.MINUTE, workStartCalendar.get(Calendar.MINUTE)); endWorkTime.set(Calendar.HOUR_OF_DAY, workEndCalendar.get(Calendar.HOUR_OF_DAY)); endWorkTime.set(Calendar.MINUTE, workEndCalendar.get(Calendar.MINUTE)); if (startTime.getTime().getTime() == endTime.getTime().getTime() || (startWorkTime.getTime().getTime() < startTime.getTime().getTime() && endWorkTime.getTime().getTime() < startTime.getTime().getTime())) { Toast.makeText(context, "时间参数错误", Toast.LENGTH_LONG).show(); return false; } startCalendar.setTime(startCalendar.getTime().getTime() < workStartCalendar.getTime().getTime() ? workStartCalendar.getTime() : startCalendar.getTime()); endCalendar.setTime(endCalendar.getTime().getTime() > workEndCalendar.getTime().getTime() ? workEndCalendar.getTime() : endCalendar.getTime()); MINHOUR = workStartCalendar.get(Calendar.HOUR_OF_DAY); MAXHOUR = workEndCalendar.get(Calendar.HOUR_OF_DAY); } return res; } private String fomatTimeUnit(int unit) { return unit < 10 ? "0" + String.valueOf(unit) : String.valueOf(unit); } private void initArrayList() { if (year == null) year = new ArrayList<>(); if (month == null) month = new ArrayList<>(); if (day == null) day = new ArrayList<>(); if (hour == null) hour = new ArrayList<>(); if (minute == null) minute = new ArrayList<>(); year.clear(); month.clear(); day.clear(); hour.clear(); minute.clear(); } private void addListener() { year_pv.seton SelectListener(new PickerView.on SelectListener() { @Override public void on Select(String text) { selectedCalender.set(Calendar.YEAR, Integer.parseInt(text)); monthChange(); } }); month_pv.seton SelectListener(new PickerView.on SelectListener() { @Override public void on Select(String text) { selectedCalender.set(Calendar.MONTH, Integer.parseInt(text) - 1); dayChange(); } }); day_pv.seton SelectListener(new PickerView.on SelectListener() { @Override public void on Select(String text) { selectedCalender.set(Calendar.DAY_OF_MONTH, Integer.parseInt(text)); hourChange(); } }); hour_pv.seton SelectListener(new PickerView.on SelectListener() { @Override public void on Select(String text) { selectedCalender.set(Calendar.HOUR_OF_DAY, Integer.parseInt(text)); minuteChange(); } }); minute_pv.seton SelectListener(new PickerView.on SelectListener() { @Override public void on Select(String text) { selectedCalender.set(Calendar.MINUTE, Integer.parseInt(text)); } }); } private void setCurDate(){ year_pv.setSelected(curYear-startYear); month_pv.setSelected(curMonth-1); day_pv.setSelected(curDay-1); hour_pv.setSelected(curHour); if (curMininute == 0) { minute_pv.setSelected(0); }else{ minute_pv.setSelected(curMininute-1); } } public void loadComponent() { year_pv.setData(year); month_pv.setData(month); day_pv.setData(day); hour_pv.setData(hour); minute_pv.setData(minute); setCurDate(); excuteScroll(); } private void excuteScroll() { year_pv.setCanScroll(year.size() > 1 && (scrollUnits & SCROLLTYPE.YEAR.value) == SCROLLTYPE.YEAR.value); month_pv.setCanScroll(month.size() > 1 && (scrollUnits & SCROLLTYPE.MONTH.value) == SCROLLTYPE.MONTH.value); day_pv.setCanScroll(day.size() > 1 && (scrollUnits & SCROLLTYPE.DAY.value) == SCROLLTYPE.DAY.value); hour_pv.setCanScroll(hour.size() > 1 && (scrollUnits & SCROLLTYPE.HOUR.value) == SCROLLTYPE.HOUR.value); minute_pv.setCanScroll(minute.size() > 1 && (scrollUnits & SCROLLTYPE.MINUTE.value) == SCROLLTYPE.MINUTE.value); } private void monthChange() { month.clear(); int selectedYear = selectedCalender.get(Calendar.YEAR); if (selectedYear == startYear) { for (int i = startMonth; i <= MAXMONTH; i++) { month.add(fomatTimeUnit(i)); } } else if (selectedYear == endYear) { for (int i = 1; i <= endMonth; i++) { month.add(fomatTimeUnit(i)); } } else { for (int i = 1; i <= MAXMONTH; i++) { month.add(fomatTimeUnit(i)); } } selectedCalender.set(Calendar.MONTH, Integer.parseInt(month.get(0)) - 1); month_pv.setData(month); month_pv.setSelected(0); excuteAnimator(ANIMATORDELAY, month_pv); month_pv.postDelayed(new Runnable() { @Override public void run() { dayChange(); } }, CHANGEDELAY); } private void dayChange() { day.clear(); int selectedYear = selectedCalender.get(Calendar.YEAR); int selectedMonth = selectedCalender.get(Calendar.MONTH) + 1; if (selectedYear == startYear && selectedMonth == startMonth) { for (int i = startDay; i <= selectedCalender.getActualMaximum(Calendar.DAY_OF_MONTH); i++) { day.add(fomatTimeUnit(i)); } } else if (selectedYear == endYear && selectedMonth == endMonth) { for (int i = 1; i <= endDay; i++) { day.add(fomatTimeUnit(i)); } } else { for (int i = 1; i <= selectedCalender.getActualMaximum(Calendar.DAY_OF_MONTH); i++) { day.add(fomatTimeUnit(i)); } } selectedCalender.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day.get(0))); day_pv.setData(day); day_pv.setSelected(0); excuteAnimator(ANIMATORDELAY, day_pv); day_pv.postDelayed(new Runnable() { @Override public void run() { hourChange(); } }, CHANGEDELAY); } private void hourChange() { hour.clear(); int selectedYear = selectedCalender.get(Calendar.YEAR); int selectedMonth = selectedCalender.get(Calendar.MONTH) + 1; int selectedDay = selectedCalender.get(Calendar.DAY_OF_MONTH); if (selectedYear == startYear && selectedMonth == startMonth && selectedDay == startDay) { for (int i = startHour; i <= MAXHOUR; i++) { hour.add(fomatTimeUnit(i)); } } else if (selectedYear == endYear && selectedMonth == endMonth && selectedDay == endDay) { for (int i = MINHOUR; i <= endHour; i++) { hour.add(fomatTimeUnit(i)); } } else { for (int i = MINHOUR; i <= MAXHOUR; i++) { hour.add(fomatTimeUnit(i)); } } selectedCalender.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour.get(0))); hour_pv.setData(hour); hour_pv.setSelected(0); excuteAnimator(ANIMATORDELAY, hour_pv); hour_pv.postDelayed(new Runnable() { @Override public void run() { minuteChange(); } }, CHANGEDELAY); } private void minuteChange() { minute.clear(); int selectedYear = selectedCalender.get(Calendar.YEAR); int selectedMonth = selectedCalender.get(Calendar.MONTH) + 1; int selectedDay = selectedCalender.get(Calendar.DAY_OF_MONTH); int selectedHour = selectedCalender.get(Calendar.HOUR_OF_DAY); if (selectedYear == startYear && selectedMonth == startMonth && selectedDay == startDay && selectedHour == startHour) { for (int i = startMininute; i <= MAXMINUTE; i++) { minute.add(fomatTimeUnit(i)); } } else if (selectedYear == endYear && selectedMonth == endMonth && selectedDay == endDay && selectedHour == endHour) { for (int i = MINMINUTE; i <= endMininute; i++) { minute.add(fomatTimeUnit(i)); } } else if (selectedHour == hour_workStart) { for (int i = minute_workStart; i <= MAXMINUTE; i++) { minute.add(fomatTimeUnit(i)); } } else if (selectedHour == hour_workEnd) { for (int i = MINMINUTE; i <= minute_workEnd; i++) { minute.add(fomatTimeUnit(i)); } } else { for (int i = MINMINUTE; i <= MAXMINUTE; i++) { minute.add(fomatTimeUnit(i)); } } selectedCalender.set(Calendar.MINUTE, Integer.parseInt(minute.get(0))); minute_pv.setData(minute); minute_pv.setSelected(0); excuteAnimator(ANIMATORDELAY, minute_pv); excuteScroll(); } private void excuteAnimator(long ANIMATORDELAY, View view) { PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 1.3f, 1f); PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f, 1.3f, 1f); ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY, pvhZ).setDuration(ANIMATORDELAY).start(); } /** * 设置选取时间文本 默认"选择" */ public void setNextBtTip(String str) { tv_select.setText(str); } public int setScrollUnit(SCROLLTYPE... scrolltypes) { scrollUnits = 0; for (SCROLLTYPE scrolltype : scrolltypes) { scrollUnits ^= scrolltype.value; } return scrollUnits; } }
第六个:xml布局datetime_dialog_selector.xml【注意里面里面的控件包名前缀记得改成自己的】
<?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"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" android:padding="10dp"> <TextView android:id="@+id/tv_cancle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:padding="10dp" android:text="取消" android:textColor="@color/colorPrimary" android:textSize="16sp" /> <TextView android:id="@+id/tv_year" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="请选择时间" android:textColor="@color/colorPrimary" android:textSize="20sp" /> <TextView android:id="@+id/tv_select" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:padding="10dp" android:text="选择" android:textColor="@color/colorPrimary" android:textSize="16sp" /> </RelativeLayout> <View android:layout_width="fill_parent" android:layout_height="0.5dp" android:background="#11112233" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:background="#ffffff" android:orientation="horizontal" android:paddingBottom="15dp" android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingTop="15dp"> <top.chinapeople.timeselector.time_selector_current.PickerView android:id="@+id/year_pv" android:layout_width="0dp" android:layout_height="160dp" android:layout_weight="3" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="年" android:textColor="#333333" android:textSize="18sp" /> <top.chinapeople.timeselector.time_selector_current.PickerView android:id="@+id/month_pv" android:layout_width="0dp" android:layout_height="160dp" android:layout_weight="2" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="月" android:textColor="#333333" android:textSize="18sp" /> <top.chinapeople.timeselector.time_selector_current.PickerView android:id="@+id/day_pv" android:layout_width="0dp" android:layout_height="160dp" android:layout_weight="2" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="日" android:textColor="#333333" android:textSize="18sp" /> <top.chinapeople.timeselector.time_selector_current.PickerView android:id="@+id/hour_pv" android:layout_width="0dp" android:layout_height="160dp" android:layout_weight="2" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="时" android:textColor="#333333" android:textSize="18sp" /> <top.chinapeople.timeselector.time_selector_current.PickerView android:id="@+id/minute_pv" android:layout_width="0dp" android:layout_height="160dp" android:layout_weight="2" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="分" android:textColor="#333333" android:textSize="18sp" /> </LinearLayout> </RelativeLayout> </LinearLayout> </LinearLayout>
第七个:styles.xml里面(values文件夹里面)添加style
<style name="time_dialog" parent="android:style/Theme.Dialog"> <item name="android:windowFrame ">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowBackground">@android:color/white</item> </style>
第八个:在你的activity里面
package top.chinapeople.timeselector.time_selector_current;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.TextView; public class MainActivity extends Activity { TextView tv_show; TimeSelector timeSelector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_show = (TextView) findViewById(R.id.tv_show); timeSelector = new TimeSelector(MainActivity.this, null, "1980-01-01 00:01", "2150-12-31 23:59"); tv_show.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { timeSelector.show(tv_show); } }); } }