精华内容
下载资源
问答
  • 仿iphone日期选择器,项目需要一个能选择开始时间和结束时间,用别人demo多封装了一次。
  • Android自定义时间控件选择开始时间到结束时间

    万次阅读 热门讨论 2017-11-30 18:01:28
    一丶效果图 二丶概述 大概是去年的这个时候说要做一个关于时间控件的总结,到这会才开始...1.选择开始时间到结束时间 2.结束时间不能超过今天 3.开始时间不能超过结束时间 4.最早选择2017年1月1日 5.仿iOS(表示很无

    本文出自:http://blog.csdn.net/dt235201314/article/details/78678419

    Android自定义时间控件选择开始时间到结束时间

    Android自定义时间控件不可选择未来时间

    一丶效果图


    二丶概述

    大概是去年的这个时候说要做一个关于时间控件的总结,到这会才开始。在整理demo时,发现直接上代码也无法由浅入深讲解,眨眼就是11月30号了,踩着11月份的尾巴,先来一篇,后面再补充。

    三丶看代码

    (1).需求分析

    1.选择开始时间到结束时间

    2.结束时间不能超过今天

    3.开始时间不能超过结束时间

    4.最早选择2017年1月1日

    5.仿iOS(表示很无奈)


    (2)看代码

    首先是一个Dialog

    DoubleTimeSelectDialog.java

    public class DoubleTimeSelectDialog extends Dialog implements View.OnClickListener{
    
        private Context mContext;
    
        /**
         * 事件选取完毕监听
         */
        private OnDateSelectFinished onDateSelectFinished;
        /**
         * 开始、结束年份
         */
        private static int START_YEAR = 1990, END_YEAR = 2100;
        /**
         * 最大年龄
         */
        private final int LARGEST_AGE = 119;
        /**
         * 年
         */
        private WheelView mYearView;
        /**
         * 月
         */
        private WheelView mMonthView;
        /**
         * 日
         */
        private WheelView mDayView;
        /**
         * 时
         */
        private WheelView mHourView;
        /**
         * 分
         */
        private WheelView mMinuteView;
        /**
         * list列表(大月份)
         */
        private List<String> mListBig;
        /**
         * list列表(小月份)
         */
        private List<String> mListLittle;
    
        /* 是否只选择本年 */
        private boolean isOnlyThisYear = false;
    
        private boolean isShowMinute = false;
        /* 是否只选择本月 */
        private boolean isOnlyThisMonth = false;
    
        public static final String YEAR = "year";
        public static final String MONTH = "month";
        public static final String DAY = "day";
        private int year;
        private int month;
        private int day;
        private int hour;
        private int minute;
    
        private int curYear;
        private int curMonth;
        private int curDay;
    
        /**时间容器*/
        private LinearLayout mTimeContainerLl;
        /**开始时间*/
        private TextView mBeginTimeTv;
        /**结束时间*/
        private TextView mEndTimeTv;
    
        /**选择的开始时间*/
        private String mSelectStartTime;
        /**选择的结束时间*/
        private String mSelectEndTime;
    
        /**当前选择时间模式*/
        private TIME_TYPE mTimeType = TIME_TYPE.TYPE_START;
    
        /**最小时间*/
        private String allowedSmallestTime;
    /**最大时间*/
    private String allowedBiggestTime;
        private enum TIME_TYPE {
            TYPE_START,
            TYPE_END
        }
    
    
    
        public DoubleTimeSelectDialog(Context context) {
            super(context, R.style.PopBottomDialogStyle);
        }
    
        public DoubleTimeSelectDialog(Context context, String curTime, String startTime) {
            super(context, R.style.PopBottomDialogStyle);
            this.mContext = context;
            this.allowedSmallestTime = startTime;
            setContentView(R.layout.popwindow_bottom_layout);
            setCanceledOnTouchOutside(true);
            Window mDialogWindow = getWindow();
            mDialogWindow.setGravity(Gravity.BOTTOM);
            WindowManager.LayoutParams lp = mDialogWindow.getAttributes();
            lp.y = 0;//设置Dialog距离底部的距离
            lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
            mDialogWindow.setAttributes(lp);
    
            initDialogView();
    
            init(curTime, false);
    
            String monthS = String.format("%02d", curMonth);
            String dayS = String.format("%02d", curDay);
            String yearS = String.format("%02d", curYear);
            if(!TextUtils.isEmpty(curTime)){
                mSelectStartTime = curTime;
                mBeginTimeTv.setText(makeFormatContent(mContext.getString(R.string.begin_at), curTime.replaceAll("-",".")));
                mSelectEndTime = curTime;
                mEndTimeTv.setText(makeFormatContent(mContext.getString(R.string.end_at), curTime.replaceAll("-",".")));
            }else{
                mSelectStartTime = yearS + "-" + monthS + "-" + dayS;
                mBeginTimeTv.setText(makeFormatContent(mContext.getString(R.string.begin_at), yearS + "." + monthS + "." + dayS));
                mSelectEndTime = yearS + "-" + monthS + "-" + dayS;
                mEndTimeTv.setText(makeFormatContent(mContext.getString(R.string.end_at), yearS + "." + monthS + "." + dayS));
            }
        }
    
        public DoubleTimeSelectDialog(Context context, String earliestTime, String startTime, String endTime) {
            super(context, R.style.PopBottomDialogStyle);
            this.mContext = context;
            this.allowedSmallestTime = earliestTime;
            this.allowedBiggestTime = endTime;
            setContentView(R.layout.popwindow_bottom_layout);
            setCanceledOnTouchOutside(true);
            Window mDialogWindow = getWindow();
            mDialogWindow.setGravity(Gravity.BOTTOM);
            WindowManager.LayoutParams lp = mDialogWindow.getAttributes();
            lp.y = 0;//设置Dialog距离底部的距离
            lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
            mDialogWindow.setAttributes(lp);
    
            initDialogView();
    
            init(startTime, false);
    
            String monthS = String.format("%02d", curMonth);
            String dayS = String.format("%02d", curDay);
            String yearS = String.format("%02d", curYear);
            if(!TextUtils.isEmpty(startTime)){
                mSelectStartTime = startTime;
                mBeginTimeTv.setText(makeFormatContent(mContext.getString(R.string.begin_at), startTime.replaceAll("-",".")));
                mSelectEndTime = endTime;
                mEndTimeTv.setText(makeFormatContent(mContext.getString(R.string.end_at), endTime.replaceAll("-",".")));
            }else{
                mSelectStartTime = yearS + "-" + monthS + "-" + dayS;
                mBeginTimeTv.setText(makeFormatContent(mContext.getString(R.string.begin_at), yearS + "." + monthS + "." + dayS));
                mSelectEndTime = yearS + "-" + monthS + "-" + dayS;
                mEndTimeTv.setText(makeFormatContent(mContext.getString(R.string.end_at), yearS + "." + monthS + "." + dayS));
            }
        }
    
        private void initDialogView () {
    
            mTimeContainerLl = (LinearLayout) findViewById(R.id.ll_tclTimeToTime);
            mBeginTimeTv = (TextView) findViewById(R.id.tv_tclBeginTime);
            mEndTimeTv = (TextView) findViewById(R.id.tv_tclEndTime);
    
            findViewById(R.id.tv_tclCancel).setOnClickListener(this);
            findViewById(R.id.tv_tclOk).setOnClickListener(this);
            mBeginTimeTv.setOnClickListener(this);
            mEndTimeTv.setOnClickListener(this);
    
        }
    
        /*恢复起始时间按钮的点击状态*/
        public void recoverButtonState(){
            mTimeType = TIME_TYPE.TYPE_START;
            init(mSelectStartTime, false);
            mTimeContainerLl.setBackgroundResource(R.mipmap.begin_time_bg);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.tv_tclBeginTime:
                    mTimeType = TIME_TYPE.TYPE_START;
                    init(mSelectStartTime, false);
                    mTimeContainerLl.setBackgroundResource(R.mipmap.begin_time_bg);
                    break;
                case R.id.tv_tclEndTime:
                    mTimeType = TIME_TYPE.TYPE_END;
                    init(mSelectEndTime, false);
                    mTimeContainerLl.setBackgroundResource(R.mipmap.end_time_bg);
                    break;
                case R.id.tv_tclCancel:
                    this.dismiss();
    
                    break;
                case R.id.tv_tclOk:
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
                    try {
                        if (sdf.parse(mSelectStartTime).getTime() > sdf.parse(mSelectEndTime).getTime()) {
                            ToastUtils.showText(mContext, R.string.time_start_larger_end_not_allowed, ToastUtils.ONE_SECOND);
                        } else {
                            if (onDateSelectFinished != null) {
                                onDateSelectFinished.onSelectFinished(mSelectStartTime, mSelectEndTime);
                            }
                            this.dismiss();
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
    
            }
        }
    
        public void init(String date, boolean isShowHour) {
            Calendar calendar = Calendar.getInstance();
            curYear = calendar.get(Calendar.YEAR);
            curMonth = calendar.get(Calendar.MONTH) + 1;
            curDay = calendar.get(Calendar.DATE);
            hour = calendar.get(Calendar.HOUR_OF_DAY);
            minute = calendar.get(Calendar.MINUTE);
    
            calendar.clear();
    
            if  (date != null) {
                String[] ymd = date.split("-");
                if (ymd.length > 2) {
                    curYear = Integer.parseInt(ymd[0]);
                    curMonth = Integer.parseInt(ymd[1]) - 1;
                    String[] dhm = ymd[2].split(" ");
                    curDay = Integer.parseInt(dhm[0]);
                    if (dhm.length > 1) {
                        String[] hm = dhm[1].split(":");
                        if (hm.length > 1) {
                            hour = Integer.parseInt(hm[0]);
                            minute = Integer.parseInt(hm[1]);
                        }
                    }
                }
            }
    
            mYearView = (WheelView) findViewById(R.id.year);
            mMonthView = (WheelView) findViewById(R.id.month);
            mDayView = (WheelView) findViewById(R.id.day);
            mHourView = (WheelView) findViewById(R.id.hour);
            mMinuteView = (WheelView) findViewById(R.id.minute);
    
            if (!isShowHour) {
                mHourView.setVisibility(View.GONE);
                mMinuteView.setVisibility(View.GONE);
            }
    
            if (!isShowMinute) {
                mMinuteView.setVisibility(View.GONE);
            }
    
            /* 年,月,日,时,分 等单位,和值同在 */
            findViewById(R.id.tv_yearUnit).setVisibility(mYearView.getVisibility());
    
            findViewById(R.id.tv_monthUnit).setVisibility(mMonthView.getVisibility());
    
            findViewById(R.id.tv_dayUnit).setVisibility(mDayView.getVisibility());
            findViewById(R.id.v_dayAndMinute).setVisibility(isShowHour ? View.VISIBLE : View.GONE);
    
            findViewById(R.id.tv_hourUnit).setVisibility(mHourView.getVisibility());
    
            findViewById(R.id.tv_minuteUnit).setVisibility(mMinuteView.getVisibility());
    
            initDatePicker();
    
            mYearView.removeChangingListener(yearWheelListener);
            mMonthView.removeChangingListener(monthWheelListener);
            mDayView.removeChangingListener(dayWheelListener);
    
            mYearView.addChangingListener(yearWheelListener);
            mMonthView.addChangingListener(monthWheelListener);
            mDayView.addChangingListener(dayWheelListener);
    
            }
        /**
         * 弹出日期时间选择器
         */
        private void initDatePicker() {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
            month = calendar.get(Calendar.MONTH);
            day = calendar.get(Calendar.DATE);
    //        END_YEAR = year;
            String[] ymd = allowedSmallestTime.split("-");
            if(TextUtils.isEmpty(allowedBiggestTime))
                allowedBiggestTime = TimeUtil.getCurData();
            String[] ymdEnd= allowedBiggestTime.split("-");
    
            if (ymd.length > 2) {
                START_YEAR = Integer.parseInt(ymd[0]);
            }
            if(ymdEnd.length>2){
                END_YEAR = Integer.parseInt(ymdEnd[0]);
                month = Integer.parseInt(ymdEnd[1])-1;
                day= Integer.parseInt(ymdEnd[2]);
            }
    
            // 添加大小月月份并将其转换为list,方便之后的判断
            String[] monthsBig = {"1", "3", "5", "7", "8", "10", "12"};
            String[] monthsLittle = {"4", "6", "9", "11"};
    
            mListBig = Arrays.asList(monthsBig);
            mListLittle = Arrays.asList(monthsLittle);
    
            // 年
            mYearView.setAdapter(new NumericWheelAdapter(START_YEAR, END_YEAR));// 设置"年"的显示数据
            mYearView.setLabel("");// 添加文字
            int yearPos = isOnlyThisYear ? END_YEAR - START_YEAR : curYear != 0 ? curYear - START_YEAR : END_YEAR - START_YEAR;
            mYearView.setCurrentItem(yearPos);// 初始化时显示的数据 START_YEAR - END_YEAR
            mYearView.setCyclic(false);// 循环滚动
    
    
            // 月
            int startMonth = 1;
            if (isOnlyThisMonth) {
                startMonth = curMonth + 1;
            }
    
            //初始年份最大值应该是当年最大月
            mMonthView.setAdapter(new NumericWheelAdapter(startMonth, year == curYear ? month + 1 : 12));
            mMonthView.setLabel("");
            mMonthView.setCurrentItem(isOnlyThisMonth ? 0 : curMonth != 0 ? curMonth : month);
            mMonthView.setCyclic(false);
    
            // 日
            //判断是否属于当前月份,如果不是,需要判断大小月,进行初始化
            if (curMonth < month){
                // 判断大小月及是否闰年,用来确定"日"的数据
                if (mListBig.contains(String.valueOf(curMonth))) {
                    mDayView.setAdapter(new NumericWheelAdapter(1, 31));
                } else if (mListLittle.contains(String.valueOf(curMonth))) {
                    mDayView.setAdapter(new NumericWheelAdapter(1, 30));
                } else {
                    if (((mYearView.getCurrentItem() + START_YEAR) % 4 == 0 && (mYearView.getCurrentItem() + START_YEAR) % 100 != 0)
                            || (mYearView.getCurrentItem() + START_YEAR) % 400 == 0)
                        mDayView.setAdapter(new NumericWheelAdapter(1, 29));
                    else
                        mDayView.setAdapter(new NumericWheelAdapter(1, 28));
                }
            }else {
                if(mTimeType == TIME_TYPE.TYPE_END){
                    mDayView.setAdapter(new NumericWheelAdapter(1, Integer.parseInt(ymdEnd[2])));
                }else if(mTimeType == TIME_TYPE.TYPE_START){
                    mDayView.setAdapter(new NumericWheelAdapter(Integer.parseInt(ymd[2]), day));
                }else{
                    mDayView.setAdapter(new NumericWheelAdapter(1, day));
                }
            }
    
            mDayView.setLabel("");
            mDayView.setCurrentItem(curDay == 0 ? day - 1 : curDay - 1);
            mDayView.setCyclic(true);
    
            // 时
            mHourView.setAdapter(new NumericWheelAdapter(0, 23));
            mHourView.setLabel("");
            mHourView.setCurrentItem(hour);
            mHourView.setCyclic(true);
    
            // 分
            mMinuteView.setAdapter(new NumericWheelAdapter(0, 59));
            mMinuteView.setLabel("");
            mMinuteView.setCurrentItem(minute);
            mMinuteView.setCyclic(true);
    
            // 选择器字体的大小
            int textSize = mContext.getResources().getDimensionPixelSize(R.dimen.ymd_text_size);
            mDayView.TEXT_SIZE = textSize;
            mMonthView.TEXT_SIZE = textSize;
            mYearView.TEXT_SIZE = textSize;
            mHourView.TEXT_SIZE = textSize;
            mMinuteView.TEXT_SIZE = textSize;
        }
    
    
        /**
         * 添加对"年"监听
         */
        private OnWheelChangedListener yearWheelListener = new OnWheelChangedListener() {
            public void onChanged(WheelView wheel, int oldValue, int newValue) {
                int year_num = newValue + START_YEAR;
                if (year_num < year) {
                    mMonthView.setAdapter(new NumericWheelAdapter(1, 12));
                } else if (year_num >= year) {
                    mMonthView.setAdapter(new NumericWheelAdapter(1, month + 1));
                }
                mMonthView.setCurrentItem(0);
                // 判断大小月及是否闰年,用来确定"日"的数据
                if (mListBig.contains(String.valueOf(mMonthView.getCurrentItem() + 1))) {
                    mDayView.setAdapter(new NumericWheelAdapter(1, 31));
                } else if (mListLittle.contains(String.valueOf(mMonthView.getCurrentItem() + 1))) {
                    mDayView.setAdapter(new NumericWheelAdapter(1, 30));
                } else {
                    if ((year_num % 4 == 0 && year_num % 100 != 0) || year_num % 400 == 0)
                        mDayView.setAdapter(new NumericWheelAdapter(1, 29));
                    else
                        mDayView.setAdapter(new NumericWheelAdapter(1, 28));
                }
                onScroll();
                mMonthView.setCurrentItem(mMonthView.getCurrentItem());
                mDayView.setCurrentItem(mDayView.getCurrentItem());
            }
        };
    
        /**
         * 添加对"月"监听
         */
        private OnWheelChangedListener monthWheelListener = new OnWheelChangedListener() {
            public void onChanged(WheelView wheel, int oldValue, int newValue) {
                int month_num = newValue + 1;
                if (month_num == (month + 1)) {
                    mDayView.setAdapter(new NumericWheelAdapter(1, day));
                } else {
                    // 判断大小月及是否闰年,用来确定"日"的数据
                    if (mListBig.contains(String.valueOf(month_num))) {
                        mDayView.setAdapter(new NumericWheelAdapter(1, 31));
                    } else if (mListLittle.contains(String.valueOf(month_num))) {
                        mDayView.setAdapter(new NumericWheelAdapter(1, 30));
                    } else {
                        if (((mYearView.getCurrentItem() + START_YEAR) % 4 == 0 && (mYearView.getCurrentItem() + START_YEAR) % 100 != 0)
                                || (mYearView.getCurrentItem() + START_YEAR) % 400 == 0)
                            mDayView.setAdapter(new NumericWheelAdapter(1, 29));
                        else
                            mDayView.setAdapter(new NumericWheelAdapter(1, 28));
                    }
                }
                onScroll();
                mDayView.setCurrentItem(mDayView.getCurrentItem());
            }
        };
    
        /**
         * 添加对 日滚动控件 的添加
         */
        private OnWheelChangedListener dayWheelListener = new OnWheelChangedListener() {
            public void onChanged(WheelView wheel, int oldValue, int newValue) {
                mDayView.setCurrentItem(newValue);
                onScroll();
            }
        };
    
        private void onScroll() {
    
                int year = isOnlyThisYear ? Integer.parseInt(mYearView.getAdapter().getItem(0))
                        : mYearView.getCurrentItem() + START_YEAR;
                int month = isOnlyThisMonth ? Integer.parseInt(mMonthView.getAdapter().getItem(0))
                        : mMonthView.getCurrentItem() + 1;
                int day = mDayView.getCurrentItem() + 1;
    
            String monthS = String.format("%02d", month);
            String dayS = String.format("%02d", day);
            String yearS = String.format("%02d", year);
    
    
            if (mTimeType == TIME_TYPE.TYPE_START) {
                mSelectStartTime = yearS + "-" + monthS + "-" + dayS;
                mBeginTimeTv.setText(makeFormatContent(mContext.getString(R.string.begin_at), yearS + "." + monthS + "." + dayS));
            } else {
                mSelectEndTime = yearS + "-" + monthS + "-" + dayS;
                mEndTimeTv.setText(makeFormatContent(mContext.getString(R.string.end_at), yearS + "." + monthS + "." + dayS));
            }
        }
    
        /**
         * 格式化显示的数据,必须返回SpannableString对象
         *
         * @param priFix  前缀
         * @param content 内容
         * @return 返回格式化的数据
         */
        private SpannableString makeFormatContent(String priFix, String content){
            SpannableString spannableString = new SpannableString(priFix + content);
            spannableString.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.color.black33)),
                    priFix.length(), spannableString.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
            spannableString.setSpan(new RelativeSizeSpan(1.33f),
                    priFix.length(), spannableString.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
            return spannableString;
        }
    
    
        /**
         * set监听
         *
         * @param onDateSelectFinished 完成监听
         */
        public void setOnDateSelectFinished(OnDateSelectFinished onDateSelectFinished) {
            this.onDateSelectFinished = onDateSelectFinished;
        }
    
        /**
         * 监听接口
         */
        public interface OnDateSelectFinished {
            /**
             * 监听方法
             *
             * @param startTime   开始时间
             * @param endTime  结束时间
             */
            void onSelectFinished(String startTime, String endTime);
        }
    
    }

    popwindow_bottom_layout.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:background="@color/withe"
        android:orientation="vertical">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="64dp"
            android:gravity="center_vertical"
            android:padding="12dp">
    
            <TextView
                android:id="@+id/tv_tclCancel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:text="@string/cancel"
                android:textColor="@color/black99"
                android:textSize="17sp" />
    
            <TextView
                android:id="@+id/tv_tclOk"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:text="@string/ok"
                android:textColor="@color/blue_bg"
                android:textSize="17sp" />
        </RelativeLayout>
    
        <LinearLayout
            android:id="@+id/ll_tclTimeToTime"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@mipmap/begin_time_bg">
    
            <TextView
                android:id="@+id/tv_tclBeginTime"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical"
                android:paddingLeft="40dp"
                android:text="结束于\n2017.05.08" />
    
            <TextView
                android:id="@+id/tv_tclEndTime"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical"
                android:paddingLeft="40dp"
                android:text="结束于\n2017.05.08" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">
    
            <include
                android:id="@+id/view_dataSelect"
                layout="@layout/data_time_layout" />
        </LinearLayout>
    
    </LinearLayout>

    data_time_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_time_title"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="12dp"
        android:layout_marginTop="12dp"
        android:orientation="horizontal">
    
        <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
            android:id="@+id/year"
            android:layout_width="92dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.2" />
    
        <TextView
            android:id="@+id/tv_yearUnit"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:text="年" />
    
        <View
            android:layout_width="1px"
            android:layout_height="fill_parent"
            android:background="#e8e8e8" />
    
        <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
            android:id="@+id/month"
            android:layout_width="92dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.2" />
    
        <TextView
            android:id="@+id/tv_monthUnit"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:text="月" />
    
        <View
            android:id="@+id/v_monthAndDay"
            android:layout_width="1px"
            android:layout_height="fill_parent"
            android:background="#e8e8e8" />
    
        <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
            android:id="@+id/day"
            android:layout_width="92dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.2" />
    
        <TextView
            android:id="@+id/tv_dayUnit"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:text="日" />
    
        <View
            android:id="@+id/v_dayAndHour"
            android:layout_width="1px"
            android:layout_height="fill_parent"
            android:background="#e8e8e8" />
    
        <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
            android:id="@+id/hour"
            android:layout_width="92dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.2" />
    
        <TextView
            android:id="@+id/tv_hourUnit"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:text="时" />
    
        <View
            android:id="@+id/v_dayAndMinute"
            android:layout_width="1px"
            android:layout_height="fill_parent"
            android:background="#e8e8e8" />
    
        <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
            android:id="@+id/minute"
            android:layout_width="92dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.2" />
    
        <TextView
            android:id="@+id/tv_minuteUnit"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:text="分" />
    </LinearLayout>

    关于WheelView后面再说,时间控件常见的轮子

    弹框样式

    <style name="PopBottomDialogStyle" parent="@android:style/Theme.Dialog">
        <!-- 背景透明 -->
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <!-- 浮于Activity之上 -->
        <item name="android:windowIsFloating">true</item>
        <!-- 边框 -->
        <item name="android:windowFrame">@null</item>
        <!-- Dialog以外的区域模糊效果 -->
        <item name="android:backgroundDimEnabled">true</item>
        <!-- 无标题 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 半透明 -->
        <item name="android:windowIsTranslucent">true</item>
        <!-- Dialog进入及退出动画 -->
        <item name="android:windowAnimationStyle">@style/ActionSheetDialogAnimation</item>
    </style>
    <!-- ActionSheet进出动画 -->
    <style name="ActionSheetDialogAnimation" parent="@android:style/Animation.Dialog">
        <item name="android:windowEnterAnimation">@anim/popwindow_enter</item>
        <item name="android:windowExitAnimation">@anim/popwindow_exit</item>
    </style>
    弹框动画

    popwindow_enter

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="200"
            android:fromYDelta="100%"
            android:toYDelta="0" />
    </set>
    popwindow_exit

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="200"
            android:fromYDelta="0"
            android:toYDelta="100%" />
    </set>
    关于时间滑动的逻辑处理和一般时间控件一样

    (这里先这么写,后面补上)

    最后使用

    一个方法:

    public void showCustomTimePicker() {
        String beginDeadTime = "2017-01-01";
        if (mDoubleTimeSelectDialog == null) {
            mDoubleTimeSelectDialog = new DoubleTimeSelectDialog(this, beginDeadTime, defaultWeekBegin, defaultWeekEnd);
            mDoubleTimeSelectDialog.setOnDateSelectFinished(new DoubleTimeSelectDialog.OnDateSelectFinished() {
                @Override
                public void onSelectFinished(String startTime, String endTime) {
                    ui_button1.setText(startTime.replace("-", ".") + "至\n" + endTime.replace("-", "."));
    
                }
            });
    
            mDoubleTimeSelectDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override
                public void onDismiss(DialogInterface dialog) {
                }
            });
        }
        if (!mDoubleTimeSelectDialog.isShowing()) {
            mDoubleTimeSelectDialog.recoverButtonState();
            mDoubleTimeSelectDialog.show();
        }
    }

    原计划写篇Android时间控件总结,后发现以这篇开头不大合适,先这样,后面补上

    四丶跪求关注下载源码,200粉小目标
    github开源代码分享,原文链接见上文
    源码下载记得顺便Star哦~

    下载链接:https://github.com/JinBoy23520/CoderToDeveloperByTCLer


    五丶BUG修改

    1.修复楼下问题ChenYao_0407

    问题分析:之前只做了2017没跨年的情况,年选择时间没有带到月监听里,导致2017年月份,依然无法当天对应月份

    解决办法:将年选择带到月份选择里

    步骤:

    (1)添加参数

    /**
     * 选择年
     */
    private int choiceYearView;

    (2)在年选择监听赋值

    int year_num = newValue + START_YEAR;
    choiceYearView = year_num;

    (3)在月监听添加判断

    if (month_num == (month + 1) && choiceYearView == year) {
        mDayView.setAdapter(new NumericWheelAdapter(1, day));
    } else {
    OK,问题解决
    展开全文
  • 利用uni-app官网里面picker插件代码,点击开始时间后结束时间要大于选择后的开始时间,点击结束时间开始时间要小于开始时间。 html代码 <view class="leave_cont"> <view class="ul"> <view...

    利用uni-app官网里面picker插件代码,点击开始时间后结束时间要大于选择后的开始时间,点击结束时间后开始时间要小于开始时间。

    html代码

    <view class="leave_cont">
    	<view class="ul">
    		<view class="li">
    			<text>开始时间</text>
    			<view class="flex1">
    				<picker mode="date" :value="start_date" :start="start_date" :end="other"  @change="bindDateChange">
    					<view class="date">{{start_date}}</view>
    				</picker>
    			</view>
    		</view>
    		<view class="li">
    			<text>结束时间</text>
    			<view class="flex1">
    				<picker mode="date" :value="start_date" :start="start_date" @change="bindDateChange2">
    					<view class="date">{{other}}</view>
    				</picker>
    			</view>
    		</view>
    	</view>
    </view>
    

    js代码

    export default {
    	data() {
    		const currentDate = this.getDate({
    			format: true
    		})
    		return {
    			start_date: currentDate,
    			end_date: currentDate,
    			other:'请输入'
    		}
    	},
    	computed: {
    		
    	},
    	methods: {
    		// 选择日期
    		bindDateChange: function(e) {
    			this.start_date = e.target.value
    			
    		},
    		bindDateChange2: function(e) {
    			this.end_date = e.target.value;
    			this.other = this.end_date;
    		},
    		// 获取当前时间
    		getDate(type) {
    			const date = new Date();
    			let year = date.getFullYear();
    			let month = date.getMonth() + 1;
    			let day = date.getDate();
    		
    			if (type === 'start') {
    				year = year - 60;
    			} else if (type === 'end') {
    				year = year + 2;
    			}
    			month = month > 9 ? month : '0' + month;;
    			day = day > 9 ? day : '0' + day;
    			return `${year}-${month}-${day}`;
    		},
    	}
    }
    

    css代码

    .leave_cont .ul{
    	padding-left: 30rpx;
    }
    .leave_cont .ul .li{
    	display: flex;
    	align-items: center;
    	border-bottom: 1px solid #efefef;
    }
    .leave_cont .ul .li text{
    	padding: 40rpx 0;
    	font-size: 34rpx;
    	font-family: '黑体';
    }
    .leave_cont .ul .li .flex1{
    	flex: 1;
    	text-align: right;
    	padding-right: 25rpx;
    	color: #999999;
    	font-size: 32rpx;
    }
    .date{
    	height: 42rpx;
    }
    (编写高质量代码,一个专业致力于页面转化,切图的前端爱好者~~)
    
    展开全文
  • //先安装moment //npm i moment //再安装Lodash,可以用它内部封装好的方法,简单实用 //npm i lodash const moment = require("moment"); const _ = require("lodash"); //假设需要查询2019-06-...//将时间转换为m...

    moment时间戳转日期=> moment.unix(时间戳).format(“YYYY-MM-DD”)

    //先安装moment
    //npm i moment
    //再安装Lodash,可以用它内部封装好的方法,简单实用
    //npm i lodash
    const moment = require("moment");
    const _ = require("lodash");
    //假设需要查询2019-06-25至2019-12-31号之间每一天的00:00至23:59这个时间段的数据
    //将时间转换为moment时间格式
    const start = "2019-06-25";//开始时间
    const start_time = moment(start);
    console.log(moment(start_time));//moment("2019-06-25T00:00:00.000")
    
    const end = "2019-12-31";
    const end_time = moment(end).endOf("d");
    console.log(end_time);//endOf("d")为当天的结束时间 moment("2019-12-31T23:59:59.999")
    
    //开始计算这两个时间段相差的天数
    const diff_times = end_time.diff(start_time,"d");
    console.log(diff_times);//189
    
    //lodash中内置的循环器,可以指定循环次数
    //再定义一个数组,用来存放相差的每一天日期
    const arr = [];
    _.times(diff_times, i => {
        const new_start_time = moment(start_time);//每次重新初始化开始时间,因为我碰到了深拷贝的问题
        arr.push(new_start_time.add(i, "days").format("YYYY-MM-DD"));//数组下标从0开始,可以用它进行每次的天数递增
    });
    //console.log(arr);
    /**
     * [ '2019-06-25',
      '2019-06-26',
      '2019-06-27',
      '2019-06-28',
      '2019-06-29',
      '2019-06-30',
      '2019-07-01',
      '2019-07-02',
      '2019-07-03',
      '2019-07-04',
      '2019-07-05',
      '2019-07-06',
      '2019-07-07',
      '2019-07-08',
      '2019-07-09',
      '2019-07-10',
      '2019-07-11',
      '2019-07-12',
      '2019-07-13'
      ... more items ]
     */
    
     //现在我们已经获取了每一天的具体日期,接下来我们就可以对这每一年的日期进行头尾运算了
     //再定义一个map循环用来存储每一天的开始和结束时间的十位时间戳
    const map = _.map(arr, v => {
        return {
            time: v,
            start_unix: moment(v).startOf('d').unix(),
            end_unix  : moment(v).endOf('d').unix()
        }
    });
    //console.log(JSON.stringify(map));
    /**
     * [
     * {"time":"2019-06-25","start_unix":1561392000,"end_unix":1561478399},
     * {"time":"2019-06-26","start_unix":1561478400,"end_unix":1561564799},
     * {"time":"2019-06-27","start_unix":1561564800,"end_unix":1561651199},
     * {"time":"2019-06-28","start_unix":1561651200,"end_unix":1561737599},
     * {"time":"2019-06-29","start_unix":1561737600,"end_unix":1561823999},
     * {"time":"2019-06-30","start_unix":1561824000,"end_unix":1561910399},
     * ..... more times ]
     */
    //至此已经完成该时间段每天的头尾时间转换了
    
    //如果需要获取某一年每个月的开始和结束时间呢?
    //我们同样的以2019-06-25这个日期为例
    const year = start.substring(0, 4);//取年份
    const clone_year = start.substring(0, 4);//再取一个年份避免moment循环引用自身
    
    //一年有12个月,在这里我们就直接循环十二次了
    //定一个用于存放月份日期的数组
    const arr_month = [];
    _.times(12, i => {
        //moment(`${i+1}/${year}`, "DD/YYYY")
        //这样做的避免了JS时间的偏移 => https://momentjs.com/guides/#/warnings/js-date/
        arr_month.push(
            {   
                month      : `${i+1} 月份`,
                start_month: moment(`${i+1}/${year}`, "MM/YYYY").add(0, "M").format("YYYY-MM-DD"),
                end_month  : moment(`${i+1}/${clone_year}`, "MM/YYYY").endOf("M").add(0, "M").format("YYYY-MM-DD")
            }
        );
    });
    //console.log(arr_month);
    
    /**
     * [ { month: '1 月份',
        start_month: '2019-01-01',
        end_month: '2019-01-31' },
      { month: '2 月份',
        start_month: '2019-02-01',
        end_month: '2019-02-28' },
      { month: '3 月份',
        start_month: '2019-03-01',
        end_month: '2019-03-31' },
      { month: '4 月份',
        start_month: '2019-04-01',
        end_month: '2019-04-30' },
      { month: '5 月份',
        start_month: '2019-05-01',
        end_month: '2019-05-31' },
      { month: '6 月份',
        start_month: '2019-06-01',
        end_month: '2019-06-30' },
      { month: '7 月份',
        start_month: '2019-07-01',
        end_month: '2019-07-31' },
      { month: '8 月份',
        start_month: '2019-08-01',
        end_month: '2019-08-31' },
      { month: '9 月份',
        start_month: '2019-09-01',
        end_month: '2019-09-30' },
      ...... more times]
     */
    
    //现在我们已经得到某一年每个月份的开始和结束时间了,我们还需要再进行时间戳转换
    const map_month = _.map(arr_month, v => {
        return {
            month           : v.month,
            start_month_unix: moment(v.start_month).startOf('d').unix(),
            end_month_unix  : moment(v.end_month).endOf('d').unix()
       }; 
    });
    console.log(map_month);
    /**
     * [ { month: '1 月份',
        start_month_unix: 1546272000,
        end_month_unix: 1548950399 },
      { month: '2 月份',
        start_month_unix: 1548950400,
        end_month_unix: 1551369599 },
      { month: '3 月份',
        start_month_unix: 1551369600,
        end_month_unix: 1554047999 },
      { month: '4 月份',
        start_month_unix: 1554048000,
        end_month_unix: 1556639999 },
      { month: '5 月份',
        start_month_unix: 1556640000,
        end_month_unix: 1559318399 },
      { month: '6 月份',
        start_month_unix: 1559318400,
        end_month_unix: 1561910399 },
      { month: '7 月份',
        start_month_unix: 1561910400,
        end_month_unix: 1564588799 },
      { month: '8 月份',
        start_month_unix: 1564588800,
        end_month_unix: 1567267199 },
        ....... more times]
     */
    
    展开全文
  • 默认值:0, 'hour',日期时间选择器所能够提供的最精确的时间选择视图。 forceParse: 0, autoclose: true, pickerPosition:'bottom-left', endDate: new Date(), }).on('changeDate',function(ev){ var ...
    $("#stratTime").datetimepicker({ 
        format: 'yyyy-mm-dd',
        language: 'zh-CN',
        weekStart: 1,
        todayBtn: 1,//显示‘今日’按钮
        autoclose: 1,
        todayHighlight: 1,
        startView: 2,
        minView: 2,  //Number, String. 默认值:0, 'hour',日期时间选择器所能够提供的最精确的时间选择视图。
        forceParse: 0,
        autoclose: true,  
        pickerPosition:'bottom-left',
        endDate: new Date(),
        }).on('changeDate',function(ev){
    
            var starttime=$("#stratTime").val();
            $("#endTime").datetimepicker('setStartDate',starttime);
            $("#stratTime").datetimepicker('hide');
    });
    
    $("#endTime").datetimepicker({ 
        format: 'yyyy-mm-dd',
        language: 'zh-CN',
        weekStart: 1,
        todayBtn: 1,//显示‘今日’按钮
        autoclose: 1,
        todayHighlight: 1,
        startView: 2,
        minView: 2,  //Number, String. 默认值:0, 'hour',日期时间选择器所能够提供的最精确的时间选择视图。
        forceParse: 0,
        autoclose: true,  
        pickerPosition:'bottom-left',
        endDate: new Date(),
    }).on('changeDate',function(ev){
        var endtime=$("#endTime").val();
        $("#stratTime").datetimepicker('setEndDate',endtime);
        $("#endTime").datetimepicker('hide'); 
    });
    
    展开全文
  • js通过开始时间和结束时间计算出中间的所有日期写在前面一 已知开始时间和结束时间 计算出中间的所有日期二 最近七天 一个月 三个月 一年 写在前面 实际开发过程中,我们有许许多多的产品都设计到了时间,也有时候...
  • 页面 <span class="searchtime">开始时间:</span> <el-date-picker size="small" v-model="searchingCondition.beginTime" type="date" :picker-options="startTime" ...
  • 3.开始时间不为空,结束时间为空,则当前时间开始时间之后,为进行中的数据 4.开始时间不为空,结束时间不为空,则当前时间开始与结束时间段之内的数据为进行中数据 下面sql则查询的是满足以上四种需求的结果集,达...
  • 软件设计师--最早开始时间和最晚开始时间

    万次阅读 多人点赞 2018-04-20 18:03:53
    先求最早开始时间:A是开始节点,所以A的最早开始时间是0,并且最早开始时间等于最晚开始时间。等得到图中红色的部分。 其他节点的最早开始时间为以该节点作为弧头的所有有向弧的值+弧尾的值 的最大值,看例子就...
  • 最近项目中用到layDate(layDate版本是5.0.9)插件,要求开始时间小于结束时间,点击清空时,清空ui组件中得选择时间.在做的过程中我发现layDate没有清空的回调函数,这时候要实现清空这种功能,该怎么办呢?废话不多说上...
  • // 设置月和日都为1,即为开始时间(注:月份是从0开始;日中0表示上个月最后一天,1表示本月开始第一天) cal. set (Calendar.MONTH, 0 ); cal. set (Calendar.DAY_OF_MONTH, 1 ); Date startDate = cal....
  • //开始时间和结束时间 写了一半 chrome竟然自动关闭了.......太阳. 给定的日期格式是yyyy-MM-dd HH:mm:dd,开始时间和结束时间都是一样的....此时计算开始时间和结束时间之间出现的天数,此时需要进行换算成毫秒数...
  • mysql获取某天的开始时间和结束时间

    千次阅读 2019-06-05 20:07:12
    mysql 根据date获取当天开始时间和结束时间 SELECT str_to_date(DATE_FORMAT(NOW(),'%Y-%m-%d'),'%Y-%m-%d %H:%i:%s'); SELECT DATE_ADD(DATE_ADD(str_to_date(DATE_FORMAT(NOW(),'%Y-%m-%d'),'%Y-%m-%d %H:%i:%s'...
  • 需求:(有效期)开始时间要小于结束时间 思路:使用el-date-picker组件的:picker-options属性,对组件进行约束。结束时间存在时,开始时间的组件框里不能选择大于结束时间的值;开始时间存在时,结束时间不能...
  • long start = System.currentTimeMillis(); for (int i = 0; i &lt; 10 ; i++) { 。。。...long end = System.currentTimeMillis();...运行时间 :" + (end - start) + "ms"); 如果用for循环的,...
  • 微信小程序开始时间,结束时间

    千次阅读 2020-02-28 13:40:50
      wxml代码: ;margin:20rpx;padding:20rpx"> ... 开始日期: {{date1}} ... // 点击开始日期组件确定事件 ... console.log("开始时间:" + startDate) console.log("结束时间" + endDate) }, })  
  • mysql实现开始时间和结束时间的查询

    万次阅读 2018-09-23 00:41:36
    1.获取当前时间 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(df.format(day)); 通过Date类来获取当前时间 2.SimpleDateFormat df= new SimpleDateFormat("yyyy-...
  • js验证开始时间和结束时间 结束时间不能比开始时间
  • 一天的开始时间 function startTime(time) { const nowTimeDate = new Date(time); return nowTimeDate.setHours(0, 0, 0, 0); } 一天的结束时间 function endTime(time) { const nowTimeDate = new Date(time);...
  • 开始时间" prop="starttime"&gt; &lt;el-date-picker v-model="model.starttime" :picker-options="startTime" type="datetime" value-format="yyyy-MM...
  • 2、order by COMMENT_TIME desc作用:根据COMMENT_TIME时间属性降序 3、limit #{startRow, jdbcType=INTEGER} , #{pageSize, jdbcType=INTEGER}作用:进行分页查询,startRow表示第几页,pageSize...
  • 判断结束时间不早于开始时间。 JS代码: function checkform(obj){ if(obj.scheduledeptContent.value == null || obj.scheduledeptContent.value == ""){ alert("日程内容不能为空!"); return ...
  • vue element-ui date-picker 日期选择器控件 设置时间范围 限制可选的开始时间和结束时间 总结一下日期控件实现开始日期、结束日期的选择范围限制,以便更符合实际情况。 需求: 1. 开始日期和结束日期都必须是...
  • Flink之Window与窗口开始时间

    千次阅读 2020-02-15 22:01:19
    窗口的开始时间是按照 TimeWindow 类的getWindowStartWithOffset方法计算,参数单位都是ms,windowSize是窗口长度 public static long getWindowStartWithOffset ( long timestamp , long offset , ...
  • WdatePicker开始时间与结束时间

    千次阅读 2019-04-26 16:35:31
    很多时候我们在一个交互的页面上需要显示两个时间让客户填写,比如开始时间&结束时间,顾名思义开始肯定不能大于结束,故使用WdatePicker插件选择时间的话可以很好的做好时间段的控制。看下面一个例子: 页面上...
  • 开始时间" prop="startTime"&gt; &lt;el-date-picker v-model="form.startTime" type="datetime" class="inputw" :picker-options="pickerOptionsStart...
  • 需求描述:开始时间要大于当前时间,结束时间要大于开始时间。 网上相关插件有很多。在此我选用了laydate,官网:https://www.layui.com/laydate/ 官网的文档,并不能完全满足需求; 通过google查资料和自己的...
  • element-ui date-picker 开始时间小于结束时间、结束时间大于开始时间且小于当前时间 &lt;div class="input-box f-left birthday-picker-box"&gt; &lt;span&gt;生日&lt;/span&...
  • 在使用RangePicker时间区间选择组件的过程中,由于业务的需要,需要对时间区间进行禁用,而且是动态的,需要根据选择的开始时间来划定结束时间的禁用范围,我以为是很简单的东西,然而,东西,反正几经周折,算是...
  • 对于每个活动,列出它的前驱,并计算最早开始时间、最晚开始时间和时差,然后确定出关键路径。 —— 《软件工程 第 4 版》中的原题 写文缘由 网上的文章大都是对于 “点” 求最早开始时间和最晚开始时间。在我看来...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,005,839
精华内容 1,602,335
关键字:

开始时间