Android:时间选择器(最下面有效果图)
1.创建DateUtil类
/**
* Created by wangshuai on 2024/11/19.
*/
public class DateUtil {
public final static String PATTERN_ALL="yyyy-MM-dd HH:mm:ss";
public final static String PATTERN_DEFAULT="yyyy-MM-dd";
/**
* 获取当前时间
* @return yyyy-MM-dd
*/
public static String getNowDate(){
Date date=new Date();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
return format.format(date);
}
/**
* 上一个月时间
* @param date 时间
* @return
*/
public static String getPreDate(String date){
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String value = "";
try {
Date now_date = df.parse(date);
Calendar g = Calendar.getInstance();
g.setTime(now_date);
g.add(Calendar.MONTH,-1);
Date pre_date = g.getTime();
value = df.format(pre_date);
} catch (ParseException e) {
e.printStackTrace();
}
return value;
}
/**
* 时间字符串转换格式
* @param date 时间
* @param oldPattern 当前模式
* @param newPattern 转换模式
* @return
*/
public static String formatDate(String date,String oldPattern, String newPattern){
DateFormat sdf_old = new SimpleDateFormat(oldPattern);
DateFormat sdf_new = new SimpleDateFormat(newPattern);
String value = "";
try {
Date date1 = sdf_old.parse(date);
value = sdf_new.format(date1);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
/**
* 时间字符串转换格式
* @param date 时间
* @param oldPattern 当前模式
* @param newPattern 转换模式
* @return
*/
public static Date formatDate(String date, String pattern){
DateFormat sdf = new SimpleDateFormat(pattern);
Date ret_date =null;
try {
ret_date = sdf.parse(date);
} catch (Exception e) {
e.printStackTrace();
}
return ret_date;
}
/**
* 时间字符串转换格式
* @param date 时间
* @param pattern 转换模式
* @return
*/
public static String formatDate(Date date, String pattern) {
String returnValue = "";
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
returnValue = df.format(date);
}
return (returnValue);
}
/**
* 判断选择的日期是否是本周
* @param time
* @return
*/
public static boolean isThisWeek(String time){
Calendar calendar = Calendar.getInstance();
int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
calendar.setTime(new Date(time));
int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
if(paramWeek==currentWeek){
return true;
}
return false;
}
/**
* 字符串转时间
* @param date
* @return
*/
public static Date str2Date(String date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* 字符串转时间
* @param date
* @return
*/
public static Date str2Date(String date, String pattern){
if (StringUtil.isEmpty(date)) {
return null;
}
try {
SimpleDateFormat df = new SimpleDateFormat(pattern);
return df.parse(date);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 判断选择的日期是否是今天
* @param date
* @return
*/
public static boolean isToday(String date) {
date = date.replaceAll(" ","");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String now = sdf.format(new Date());//当前时间
if(date.equals(now)){
return true;
}
return false;
}
/**
* 判断选择的日期是否是本月
* @param time
* @return
*/
public static boolean isThisMonth(String time) {
Date date = str2Date(time);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
String param = sdf.format(date);//参数时间
String now = sdf.format(new Date());//当前时间
if(param.equals(now)){
return true;
}
return false;
}
/**
* 增加分钟
* @param date
* @param addMin
* @return
*/
public static String addMin(Date date,int addMin){
String returnValue = "";
if(date!=null){
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MINUTE,addMin);
Date ret_date = calendar.getTime();
returnValue = formatDate(ret_date, "yyyy-MM-dd HH:mm");
} catch (Exception e) {
// TODO: handle exception
}
}
return returnValue;
}
/**
* 比较两个时间
* @param firstDate
* @param secDate
* @return
*/
public static boolean isBefore(Date firstDate,Date secDate){
return firstDate.before(secDate);
}
/**
* 比较两个时间
* @param firstDate
* @param secDate
* @return
*/
public static boolean isBefore(String firstDate,String secDate,String pattern){
try {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date tmp_first = sdf.parse(firstDate);
Date tmp_sec = sdf.parse(secDate);
return tmp_first.before(tmp_sec);
} catch (Exception e) {
// TODO: handle exception
}
return false;
}
/**
* 比较两个时间
* @param firstDate
* @param secDate
* @return
*/
public static boolean isBeforeAequals(String firstDate,String secDate,String pattern){
try {
if(firstDate.equals(secDate)){return true;}
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date tmp_first = sdf.parse(firstDate);
Date tmp_sec = sdf.parse(secDate);
return tmp_first.before(tmp_sec);
} catch (Exception e) {
// TODO: handle exception
}
return false;
}
public static int getYear(String date,String pattern){
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(formatDate(date, pattern));
return calendar.get(Calendar.YEAR);
} catch (Exception e) {
String da="";
}
return -1;
}
public static int getMonth(String date,String pattern){
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(formatDate(date, pattern));
return calendar.get(Calendar.MONTH)+1;
} catch (Exception e) {
// TODO: handle exception
}
return -1;
}
public static int getDay(String date,String pattern){
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(formatDate(date, pattern));
return calendar.get(Calendar.DATE);
} catch (Exception e) {
// TODO: handle exception
}
return -1;
}
public static int getDayOfMonth(String date,String pattern){
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(formatDate(date, pattern));
calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
} catch (Exception e) {
// TODO: handle exception
}
return -1;
}
public static int getHour(String date,String pattern){
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(formatDate(date, pattern));
return calendar.get(Calendar.HOUR_OF_DAY);
} catch (Exception e) {
// TODO: handle exception
}
return -1;
}
public static int getMinute(String date,String pattern){
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(formatDate(date, pattern));
return calendar.get(Calendar.MINUTE);
} catch (Exception e) {
// TODO: handle exception
}
return -1;
}
public static int getSecond(String date,String pattern){
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(formatDate(date, pattern));
return calendar.get(Calendar.SECOND);
} catch (Exception e) {
// TODO: handle exception
}
return -1;
}
}
2.创建DecimalUtil
import java.text.DecimalFormat;
/**
* Created by wangshuai on 2024/11/19.
*/
public class DecimalUtil {
public static String keep2zero_head(String str){
try {
DecimalFormat df=new DecimalFormat("00");
return df.format(Integer.parseInt(str));
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
}
3.创建PickerView
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
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;
/**
* 滚动选择器 更多详解见博客http://blog.csdn.net/zhongkejingwang/article/details/38513301
*
* @author wangshuai
*
*/
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;
private float mMaxTextSize = 80;
private float mMinTextSize = 40;
private float mMaxTextAlpha = 255;
private float mMinTextAlpha = 120;
private int mColorText = 0x333333;
private int mViewHeight;
private int mViewWidth;
private float mLastDownY;
/**
* 滑动的距离
*/
private float mMoveLen = 0;
private boolean isInit = false;
private onSelectListener 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();
}
};
public PickerView(Context context)
{
super(context);
init();
}
public PickerView(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
public void setOnSelectListener(onSelectListener listener)
{
mSelectListener = listener;
}
private void performSelect()
{
if (mSelectListener != null)
mSelectListener.onSelect(mDataList.get(mCurrentSelected));
}
public void setData(List<String> datas)
{
mDataList = datas;
mCurrentSelected = datas.size() / 2;
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;
}
}
//获取当前选择
public String getSelected(){
try {
return mDataList.get(mCurrentSelected);
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
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>();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Style.FILL);
mPaint.setTextAlign(Align.CENTER);
mPaint.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 = (float) (MARGIN_ALPHA * mMinTextSize * position + type
* mMoveLen);
float scale = parabola(mViewHeight / 4.0f, d);
float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize;
mPaint.setTextSize(size);
mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha));
float y = (float) (mViewHeight / 2.0 + type * d);
FontMetricsInt fmi = mPaint.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, mPaint);
}
/**
* 抛物线
*
* @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 onSelectListener
{
void onSelect(String text);
}
}
4.创建StringUtil
/**
* Created by wangshuai on 2024/11/19.
*/
public class StringUtil {
public static boolean isEmpty(Object obj){
if(obj != null && !obj.toString().trim().isEmpty()&&!"null".equals(obj.toString())) {
return false;
}
return true;
}
}
5.创建布局文件popwin_picker_view
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llt_all"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:background="#FFFFFF">
<com.ybgc.acceptanceofconcealedwork.divview.SupperTextView
android:id="@+id/tvw_cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textColor="#333333"
android:textSize="16sp"
android:text="取消"/>
<com.ybgc.acceptanceofconcealedwork.divview.SupperTextView
android:id="@+id/tvw_confirm"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textColor="#333333"
android:textSize="16sp"
android:text="确定"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#E5E5E5"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#ffffff"
android:padding="10dp"
android:gravity="center_vertical"
android:clickable="true">
<com.ybgc.acceptanceofconcealedwork.timerpicker.PickerView
android:id="@+id/pvw_year"
android:layout_width="0dp"
android:layout_height="160dp"
android:layout_weight="3" />
<com.ybgc.acceptanceofconcealedwork.divview.SupperTextView
android:id="@+id/tvw_year"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="年"
android:textColor="#333333"
android:textSize="18sp"
android:textStyle="bold" />
<com.ybgc.acceptanceofconcealedwork.timerpicker.PickerView
android:id="@+id/pvw_month"
android:layout_width="0dp"
android:layout_height="160dp"
android:layout_weight="2" />
<com.ybgc.acceptanceofconcealedwork.divview.SupperTextView
android:id="@+id/tvw_month"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="月"
android:textColor="#333333"
android:textSize="18sp"
android:textStyle="bold" />
<com.ybgc.acceptanceofconcealedwork.timerpicker.PickerView
android:id="@+id/pvw_day"
android:layout_width="0dp"
android:layout_height="160dp"
android:layout_weight="2" />
<com.ybgc.acceptanceofconcealedwork.divview.SupperTextView
android:id="@+id/tvw_day"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="日"
android:textColor="#333333"
android:textSize="18sp"
android:textStyle="bold" />
<!--时分秒 -->
<com.ybgc.acceptanceofconcealedwork.timerpicker.PickerView
android:id="@+id/pvw_hour"
android:layout_width="0dp"
android:layout_height="160dp"
android:layout_weight="2"
/>
<com.ybgc.acceptanceofconcealedwork.divview.SupperTextView
android:id="@+id/tvw_hour"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="时"
android:textColor="#333333"
android:textSize="18sp"
android:textStyle="bold"
/>
<com.ybgc.acceptanceofconcealedwork.timerpicker.PickerView
android:id="@+id/pvw_minute"
android:layout_width="0dp"
android:layout_height="160dp"
android:layout_weight="2"
/>
<com.ybgc.acceptanceofconcealedwork.divview.SupperTextView
android:id="@+id/tvw_minute"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="分"
android:textColor="#333333"
android:textSize="18sp"
android:textStyle="bold"
/>
<com.ybgc.acceptanceofconcealedwork.timerpicker.PickerView
android:id="@+id/pvw_second"
android:layout_width="0dp"
android:layout_height="160dp"
android:layout_weight="2"
/>
<com.ybgc.acceptanceofconcealedwork.divview.SupperTextView
android:id="@+id/tvw_second"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="秒"
android:textColor="#333333"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
6.创建TimerPickerView
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.ybgc.acceptanceofconcealedwork.R;
import com.ybgc.acceptanceofconcealedwork.timerpicker.PickerView.onSelectListener;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
/**
* 时间选择控件
*
* @author wangshuai
*/
public class TimePickerView extends PopupWindow {
public final static String DISPLAY_YMD = "yyyy-MM-dd";
public final static String DISPLAY_YMDHMS = "yyyy-MM-dd HH:mm:ss";
public final static String DISPLAY_YMDHM = "yyyy-MM-dd HH:mm";
public final static String DISPLAY_HMS = "HH:mm:ss";
public final static String DISPLAY_HM = "HH:mm";
private final long ANIMATORDELAY = 200L;
private final long CHANGEDELAY = 90L;
private Context mContext;
private PickerView pvw_year;
private PickerView pvw_month;
private PickerView pvw_day;
private PickerView pvw_hour;
private PickerView pvw_minute;
private PickerView pvw_second;
private TextView tvw_year;
private TextView tvw_month;
private TextView tvw_day;
private TextView tvw_hour;
private TextView tvw_minute;
private TextView tvw_second;
private List<String> year_list;
private List<String> month_list;
private List<String> day_list;
private List<String> hour_list;
private List<String> min_list;
private List<String> sec_list;
private String mode;//显示模式
private String startTime = "1970-01-01 00:00:00";
private String endTime = "2099-12-31 00:00:00";
private String displayTime;//显示时间
private String select_year;//年
private String select_month;//月
private String select_day;//日
private String select_hour;//时
private String select_minute;//分
private String select_second;//秒
private boolean isDisplayPastTime;//是否显示过去时间
private onTimeSelectListener onTimeSelectListener;
public TimePickerView(Context context) {
this.mContext = context;
this.isDisplayPastTime = true;
initView();
}
private void initView() {
View view = LayoutInflater.from(mContext).inflate(R.layout.popwin_picker_view, null);
initShowView(view);
setWidth(LayoutParams.MATCH_PARENT);
setHeight(LayoutParams.MATCH_PARENT);
setBackgroundDrawable(new ColorDrawable(0x80000000));
setOutsideTouchable(false);
setTouchable(true);
setContentView(view);
}
private void initShowView(View view) {
mode = DISPLAY_YMDHMS;
LinearLayout llt_all = view.findViewById(R.id.llt_all);
TextView tvw_cancel = view.findViewById(R.id.tvw_cancel);
TextView tvw_confirm = view.findViewById(R.id.tvw_confirm);
pvw_year = view.findViewById(R.id.pvw_year);
pvw_month = view.findViewById(R.id.pvw_month);
pvw_day = view.findViewById(R.id.pvw_day);
pvw_hour = view.findViewById(R.id.pvw_hour);
pvw_minute = view.findViewById(R.id.pvw_minute);
pvw_second = view.findViewById(R.id.pvw_second);
tvw_year = view.findViewById(R.id.tvw_year);
tvw_month = view.findViewById(R.id.tvw_month);
tvw_day = view.findViewById(R.id.tvw_day);
tvw_hour = view.findViewById(R.id.tvw_hour);
tvw_minute = view.findViewById(R.id.tvw_minute);
tvw_second = view.findViewById(R.id.tvw_second);
initDisplayMode();//设置显示效果
llt_all.setOnClickListener(cancel_onClick);
tvw_cancel.setOnClickListener(cancel_onClick);
tvw_confirm.setOnClickListener(tvw_confirm_onClick);
pvw_year.setOnSelectListener(year_onSelect);
pvw_month.setOnSelectListener(month_onSelect);
pvw_day.setOnSelectListener(day_onSelect);
pvw_hour.setOnSelectListener(hour_onSelect);
pvw_minute.setOnSelectListener(min_onSelect);
pvw_second.setOnSelectListener(sec_onSelect);
}
//初始化数据
private void initData() {
year_list = new ArrayList<String>();
month_list = new ArrayList<String>();
day_list = new ArrayList<String>();
hour_list = new ArrayList<String>();
min_list = new ArrayList<String>();
sec_list = new ArrayList<String>();
initYear();
initMonth(false);
initDay(false);
initHour(false);
initMinute(false);
initSecond(false);
sec_list.addAll(min_list);
pvw_year.setData(year_list);
pvw_month.setData(month_list);
pvw_day.setData(day_list);
pvw_hour.setData(hour_list);
pvw_minute.setData(min_list);
pvw_second.setData(sec_list);
}
//初始年
private void initYear() {
int start_year = DateUtil.getYear(startTime, DateUtil.PATTERN_ALL);
int end_year = DateUtil.getYear(endTime, DateUtil.PATTERN_ALL);
year_list.clear();
for (int i = start_year; i <= end_year; i++) {
year_list.add(i + "");
}
}
//初始月
private void initMonth(boolean isSlide) {
int start_month = DateUtil.getMonth(startTime, DateUtil.PATTERN_ALL);
int start_year = DateUtil.getYear(startTime, DateUtil.PATTERN_ALL);
if (!select_year.equals(DecimalUtil.keep2zero_head(start_year + ""))) {
start_month = 1;
}
month_list.clear();
for (int i = start_month; i <= 12; i++) {
month_list.add(DecimalUtil.keep2zero_head(i + ""));
}
if (isSlide) {
pvw_month.invalidate();
pvw_month.setSelected(0);
select_month = pvw_month.getSelected();
excuteAnimator(ANIMATORDELAY, pvw_month);
pvw_month.postDelayed(new Runnable() {
@Override
public void run() {
initDay(true);
}
}, CHANGEDELAY);
}
}
//初始日
private void initDay(boolean isSlide) {
int start_day = DateUtil.getDay(startTime, DateUtil.PATTERN_ALL);
int day_of_month = DateUtil.getDayOfMonth(startTime, DateUtil.PATTERN_ALL);
int start_year = DateUtil.getYear(startTime, DateUtil.PATTERN_ALL);
int start_month = DateUtil.getMonth(startTime, DateUtil.PATTERN_ALL);
String select_time = select_year + "-" + select_month;
String start_time = start_year + "-" + DecimalUtil.keep2zero_head(start_month + "");
//判断当前选择时间是否是开始时间
if (!select_time.equals(start_time)) {
start_day = 1;
}
String now_time = select_year + "-" + select_month + "-01 00:00:00";
day_of_month = DateUtil.getDayOfMonth(now_time, DateUtil.PATTERN_ALL);
day_list.clear();
for (int i = start_day; i <= day_of_month; i++) {
day_list.add(DecimalUtil.keep2zero_head(i + ""));
}
//滑动时执行
if (isSlide) {
pvw_day.invalidate();
pvw_day.setSelected(0);
select_day = pvw_day.getSelected();
excuteAnimator(ANIMATORDELAY, pvw_day);
pvw_day.postDelayed(new Runnable() {
@Override
public void run() {
initHour(true);
}
}, CHANGEDELAY);
}
}
//初始时
private void initHour(boolean isSlide) {
int start_hour = DateUtil.getHour(startTime, DateUtil.PATTERN_ALL);
int start_year = DateUtil.getYear(startTime, DateUtil.PATTERN_ALL);
int start_month = DateUtil.getMonth(startTime, DateUtil.PATTERN_ALL);
int start_day = DateUtil.getDay(startTime, DateUtil.PATTERN_ALL);
String select_time = select_year + "-" + select_month + "-" + select_day;
String start_time = start_year + "-" + DecimalUtil.keep2zero_head(start_month + "") + "-"
+ DecimalUtil.keep2zero_head(start_day + "");
if (!select_time.equals(start_time)) {
start_hour = 0;
}
hour_list.clear();
for (int i = start_hour; i < 24; i++) {
hour_list.add(DecimalUtil.keep2zero_head(i + ""));
}
if (isSlide) {
pvw_hour.invalidate();
pvw_hour.setSelected(0);
select_hour = pvw_hour.getSelected();
excuteAnimator(ANIMATORDELAY, pvw_hour);
pvw_hour.postDelayed(new Runnable() {
@Override
public void run() {
initMinute(true);
}
}, CHANGEDELAY);
}
}
//初始分
private void initMinute(boolean isSlide) {
int start_min = DateUtil.getMinute(startTime, DateUtil.PATTERN_ALL);
int start_year = DateUtil.getYear(startTime, DateUtil.PATTERN_ALL);
int start_month = DateUtil.getMonth(startTime, DateUtil.PATTERN_ALL);
int start_day = DateUtil.getDay(startTime, DateUtil.PATTERN_ALL);
int start_hour = DateUtil.getHour(startTime, DateUtil.PATTERN_ALL);
String select_time = select_year + "-" + select_month + "-" + select_day + " " + select_hour;
String start_time = start_year + "-" + DecimalUtil.keep2zero_head(start_month + "") + "-"
+ DecimalUtil.keep2zero_head(start_day + "") + " " + DecimalUtil.keep2zero_head(start_hour + "");
if (!select_time.equals(start_time)) {
start_min = 0;
}
min_list.clear();
for (int i = start_min; i < 60; i++) {
min_list.add(DecimalUtil.keep2zero_head(i + ""));
}
if (isSlide) {
pvw_minute.invalidate();
pvw_minute.setSelected(0);
select_minute = pvw_minute.getSelected();
excuteAnimator(ANIMATORDELAY, pvw_minute);
pvw_minute.postDelayed(new Runnable() {
@Override
public void run() {
initSecond(true);
}
}, CHANGEDELAY);
}
}
//初始秒
private void initSecond(boolean isSlide) {
int start_sec = DateUtil.getSecond(startTime, DateUtil.PATTERN_ALL);
int start_year = DateUtil.getYear(startTime, DateUtil.PATTERN_ALL);
int start_month = DateUtil.getMonth(startTime, DateUtil.PATTERN_ALL);
int start_day = DateUtil.getDay(startTime, DateUtil.PATTERN_ALL);
int start_hour = DateUtil.getHour(startTime, DateUtil.PATTERN_ALL);
int start_min = DateUtil.getMinute(startTime, DateUtil.PATTERN_ALL);
String select_time = select_year + "-" + select_month + "-" + select_day + " " + select_hour + ":" + select_minute;
String start_time = start_year + "-" + DecimalUtil.keep2zero_head(start_month + "") + "-"
+ DecimalUtil.keep2zero_head(start_day + "") + " " + DecimalUtil.keep2zero_head(start_hour + "") + ":"
+ DecimalUtil.keep2zero_head(start_min + "");
if (!select_time.equals(start_time)) {
start_sec = 0;
}
sec_list.clear();
for (int i = start_sec; i < 60; i++) {
sec_list.add(DecimalUtil.keep2zero_head(i + ""));
}
if (isSlide) {
pvw_second.invalidate();
pvw_second.setSelected(0);
select_second = pvw_second.getSelected();
excuteAnimator(ANIMATORDELAY, pvw_second);
}
}
//初始化显示
private void initDisplayMode() {
pvw_year.setVisibility(View.VISIBLE);
pvw_month.setVisibility(View.VISIBLE);
pvw_day.setVisibility(View.VISIBLE);
pvw_hour.setVisibility(View.VISIBLE);
pvw_minute.setVisibility(View.VISIBLE);
pvw_second.setVisibility(View.VISIBLE);
tvw_year.setVisibility(View.VISIBLE);
tvw_month.setVisibility(View.VISIBLE);
tvw_day.setVisibility(View.VISIBLE);
tvw_hour.setVisibility(View.VISIBLE);
tvw_minute.setVisibility(View.VISIBLE);
tvw_second.setVisibility(View.VISIBLE);
switch (mode) {
case DISPLAY_YMD:
pvw_hour.setVisibility(View.GONE);
pvw_minute.setVisibility(View.GONE);
pvw_second.setVisibility(View.GONE);
tvw_hour.setVisibility(View.GONE);
tvw_minute.setVisibility(View.GONE);
tvw_second.setVisibility(View.GONE);
break;
case DISPLAY_YMDHM:
pvw_second.setVisibility(View.GONE);
tvw_second.setVisibility(View.GONE);
break;
case DISPLAY_HMS:
pvw_year.setVisibility(View.GONE);
pvw_month.setVisibility(View.GONE);
pvw_day.setVisibility(View.GONE);
tvw_year.setVisibility(View.GONE);
tvw_month.setVisibility(View.GONE);
tvw_day.setVisibility(View.GONE);
break;
case DISPLAY_HM:
pvw_year.setVisibility(View.GONE);
pvw_month.setVisibility(View.GONE);
pvw_day.setVisibility(View.GONE);
pvw_second.setVisibility(View.GONE);
tvw_year.setVisibility(View.GONE);
tvw_month.setVisibility(View.GONE);
tvw_day.setVisibility(View.GONE);
tvw_second.setVisibility(View.GONE);
default:
break;
}
}
//初始化显示数据
private void initPickViewDisplayData() {
try {
if (StringUtil.isEmpty(displayTime)) {
pvw_year.setSelected(0);
pvw_month.setSelected(0);
pvw_day.setSelected(0);
pvw_hour.setSelected(0);
pvw_minute.setSelected(0);
pvw_second.setSelected(0);
select_year = pvw_year.getSelected();
select_month = pvw_month.getSelected();
select_day = pvw_day.getSelected();
select_hour = pvw_hour.getSelected();
select_minute = pvw_minute.getSelected();
select_second = pvw_second.getSelected();
} else {
Date date = DateUtil.str2Date(displayTime, mode);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
select_year = DateUtil.getYear(startTime, DateUtil.PATTERN_ALL) + "";
select_month = DecimalUtil.keep2zero_head(DateUtil.getMonth(startTime, DateUtil.PATTERN_ALL) + "");
select_day = DecimalUtil.keep2zero_head(DateUtil.getDay(startTime, DateUtil.PATTERN_ALL) + "");
select_hour = DecimalUtil.keep2zero_head(DateUtil.getHour(startTime, DateUtil.PATTERN_ALL) + "");
select_minute = DecimalUtil.keep2zero_head(DateUtil.getMinute(startTime, DateUtil.PATTERN_ALL) + "");
select_second = DecimalUtil.keep2zero_head(DateUtil.getSecond(startTime, DateUtil.PATTERN_ALL) + "");
switch (mode) {
case DISPLAY_YMDHMS://yyyy-MM-dd HH:mm:ss
select_year = calendar.get(Calendar.YEAR) + "";
select_month = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.MONTH) + 1));
select_day = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.DATE)));
select_hour = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.HOUR_OF_DAY)));
select_minute = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.MINUTE)));
select_second = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.SECOND)));
initData();
pvw_year.setSelected(select_year);
pvw_month.setSelected(select_month);
pvw_day.setSelected(select_day);
pvw_hour.setSelected(select_hour);
pvw_minute.setSelected(select_minute);
pvw_second.setSelected(select_second);
break;
case DISPLAY_YMDHM://yyyy-MM-dd HH:mm
select_year = calendar.get(Calendar.YEAR) + "";
select_month = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.MONTH) + 1));
select_day = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.DATE)));
select_hour = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.HOUR_OF_DAY)));
select_minute = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.MINUTE)));
initData();
pvw_year.setSelected(select_year);
pvw_month.setSelected(select_month);
pvw_day.setSelected(select_day);
pvw_hour.setSelected(select_hour);
pvw_minute.setSelected(select_minute);
break;
case DISPLAY_YMD://yyyy-MM-dd
select_year = calendar.get(Calendar.YEAR) + "";
select_month = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.MONTH) + 1));
select_day = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.DATE)));
initData();
pvw_year.setSelected(select_year);
pvw_month.setSelected(select_month);
pvw_day.setSelected(select_day);
break;
case DISPLAY_HMS://HH:mm:ss
select_hour = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.HOUR_OF_DAY)));
select_minute = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.MINUTE)));
select_second = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.SECOND)));
initData();
pvw_hour.setSelected(select_hour);
pvw_minute.setSelected(select_minute);
pvw_second.setSelected(select_second);
break;
case DISPLAY_HM://HH:mm:ss
select_hour = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.HOUR_OF_DAY)));
select_minute = DecimalUtil.keep2zero_head("" + (calendar.get(Calendar.MINUTE)));
initData();
pvw_hour.setSelected(select_hour);
pvw_minute.setSelected(select_minute);
break;
default:
break;
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
//消失
private OnClickListener cancel_onClick = new OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
};
//确认
private OnClickListener tvw_confirm_onClick = new OnClickListener() {
@Override
public void onClick(View v) {
String select_time = "";
switch (mode) {
case DISPLAY_YMDHMS:
select_time = select_year + "-" + select_month + "-" + select_day + " " + select_hour + ":" + select_minute + ":" + select_second;
break;
case DISPLAY_YMDHM:
select_time = select_year + "-" + select_month + "-" + select_day + " " + select_hour + ":" + select_minute;
break;
case DISPLAY_YMD:
select_time = select_year + "-" + select_month + "-" + select_day;
break;
case DISPLAY_HMS:
select_time = select_hour + ":" + select_minute + ":" + select_second;
break;
case DISPLAY_HM:
select_time = select_hour + ":" + select_minute;
break;
default:
break;
}
if (onTimeSelectListener != null) {
onTimeSelectListener.onSelect(select_time);
}
dismiss();
}
};
//设置显示模式
public void setMode(String mode) {
this.mode = mode;
initDisplayMode();
}
//显示时间
public void showPopWin(View view, String time) {
displayTime = time;
initPickViewDisplayData();
showAtLocation(view, Gravity.BOTTOM, 0, 0);
}
//显示时间控件
public void showPopWin(View view) {
displayTime = null;
initPickViewDisplayData();
showAtLocation(view, Gravity.BOTTOM, 0, 0);
}
//显示当前时间
public void showPopWinPresentTime(View view) {
String displayTime = DateUtil.formatDate(new Date(), mode);
showPopWin(view, displayTime);
}
//设置是否显示过去时间
public void setIsDisplayPastTime(boolean isDisplayPastTime) {
this.isDisplayPastTime = isDisplayPastTime;
if (!isDisplayPastTime) {
startTime = DateUtil.formatDate(new Date(), DISPLAY_YMDHMS);
}
}
//年选择监听
private onSelectListener year_onSelect = new onSelectListener() {
@Override
public void onSelect(String text) {
select_year = text;
initMonth(true);
}
};
//月选择监听
private onSelectListener month_onSelect = new onSelectListener() {
@Override
public synchronized void onSelect(String text) {
select_month = text;
initDay(true);
}
};
//日选择监听
private onSelectListener day_onSelect = new onSelectListener() {
@Override
public void onSelect(String text) {
select_day = text;
initHour(true);
}
};
//时选择监听
private onSelectListener hour_onSelect = new onSelectListener() {
@Override
public void onSelect(String text) {
select_hour = text;
initMinute(true);
}
};
//分选择监听
private onSelectListener min_onSelect = new onSelectListener() {
@Override
public void onSelect(String text) {
select_minute = text;
initSecond(true);
}
};
//秒选择监听
private PickerView.onSelectListener sec_onSelect = new onSelectListener() {
@Override
public void onSelect(String text) {
select_second = text;
}
};
//动画
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 interface onTimeSelectListener {
void onSelect(String time);
}
public void setOnTimeSelectListener(onTimeSelectListener onTimeSelectListener) {
this.onTimeSelectListener = onTimeSelectListener;
}
}
7.页面中使用时间选择器(点击事件中调用时间选择器)
/**
* 初始化时间选择器
*/
private TimePickerView timePickerView;//时间选择器
private void initTimePickerView(View v) {
if (timePickerView != null && !timePickerView.isShowing()) {
timePickerView.dismiss();
timePickerView = null;
}
timePickerView = new TimePickerView(ActivityLaunchApplication.this);
timePickerView.setMode(TimePickerView.DISPLAY_YMDHM);
//timePickerView.setIsDisplayPastTime(false);
String time = "";
if (StringUtil.isEmpty(time)) {
time = DateUtil.formatDate(new Date(), TimePickerView.DISPLAY_YMDHM);
}
timePickerView.showPopWin(v, time);
timePickerView.setOnTimeSelectListener(new TimePickerView.onTimeSelectListener() {
@Override
public void onSelect(String time) {//所选时间
hopeAcceptDate = time;
stvYsSj.setText(time);
}
});
}
8.效果图