精华内容
下载资源
问答
  • 2021-07-21 14:25:10

    请添加图片描述
    具体的实现方法就是使用小程序中的picker-view组件 https://uniapp.dcloud.io/component/picker-view

    注意:pop是我引入的一个弹窗组件

    <pop ref="pops" :direction="directions" :is_close="true" :is_mask="true" :width="100">
    			 <picker-view v-if="visible" :indicator-style="indicatorStyle" :value="value" @change="bindChange" class="picker-view" mask-style="width: 80rpx;">
    				<picker-view-column >
    					<view  class="item" v-for="(item,index) in popleft" :key="index">{{item}}</view>
    				</picker-view-column>
    				<picker-view-column>
    					<view class="item" v-for="(item,index) in popright" :key="index">{{item}}</view>
    				</picker-view-column>
    			</picker-view>
    			<view class="btns"@click="onsuer">确定</view>
    		</pop>
    
    export default {
    		components: {
    			pop
    		},
    		data() {
    			let popright = ['立即上门','00.00-01.00','01.00-02.00','02.00-03.00','03.00-04.00','04.00-05.00','05.00-06.00','06.00-07.00','07.00-08.00','08.00-09.00','09.00-10.00','10.00-11.00','11.00-12.00','12.00-13.00','13.00-14.00','14.00-15.00','15.00-16.00','16.00-17.00','17.00-18.00','18.00-19.00','19.00-20.00','20.00-21.00','21.00-22.00','22.00-23.00','23.00-24.00']
    			return{
    				value: [0,0],
    				indicatorStyle: `height: 50px;`,
    				popleft:['今天','明天'],
    				visible: true,
    				popright:popright,
    			}
    		},
    			methods:{
    				bindChange: function (e) {
    					console.log(e,'----126---')
    				},
    			}
    }
    

    style

    <style scoped lang="less">
    .picker-view {
          width: 100%;
          height: 255rpx;
          margin-top: 20rpx;
      }
      .item {
          height: 77rpx;
    	  line-height: 77rpx;
          align-items: center;
          justify-content: center;
          text-align: center;
      }
      .btns{
    	width: 100%;
    	height: 98rpx;
    	line-height: 98rpx;
    	background: #FFD508;
    	font-size: 42rpx;
    	font-family: PingFangSC;
    	font-weight: 500;
    	color: #FFFFFF;
    	text-align: center;
    	margin-top: 20rpx;
    }
    	  </style>
    

    关于里面pop弹窗的组件 具体是这个https://ext.dcloud.net.cn/plugin?id=2716 用其他的也行 比如uview的弹出层都可以
    里面的东西其实都可以变化 比如只想用单列那么就只循环一个就行了注意数据的循环。如果有不懂的可以留言。

    现可以接单,有需要的可以私聊或者加QQ1615313820

    更多相关内容
  • 根据周每天的每小时划分成个个小区域,自定义选择区域,获取时间选择。网上没找到符合要求的就自己整理了个插件。2种模式,种每节为小时,种每节为半小时。
  • 想实现个可以选择年份和时间段的日期选择器,如下所示 微信小程序自带的picker组件虽然能实现如上的内容,但不能实现样式的修改,不太符合小程序的设计主题,所以考虑了以下两种方法来实现如上的设计。 自定义...

    想实现一个可以选择年份和时间段的日期选择器,如下所示

    微信小程序自带的picker组件虽然能实现如上的内容,但不能实现样式的修改,不太符合小程序的设计主题,所以考虑了以下两种方法来实现如上的设计。

    1.自定义date-picker

    把要实现的date-picker封装为一个组件,组件内套用小程序自带的picker-view组件,其中picker_view-column表示不同的选择列,这样可以方便地实现样式的自定义。

    实现效果:

    具体实现

    wxml文件:

    <view class="mask" wx:if="{{isShow}}" catchtap="cancel">
      <view class="content" style="height:800rpx" animation="{{animation}}">
        <view class="top">
          <view class="top-text top-left-color" hover-class="top-left-color-hover" catchtap="cancel">取消</view>
          <view class="top-text top-right-color" hover-class="top-right-color-hover" catchtap="confirm">确定</view>
        </view>
        <picker-view style="width: 100%; height: 80%;" value="{{value}}" bindchange="change" catchtap="no">
          <picker-view-column>
            <view wx:for="{{date_list}}" wx:key="date_list" class="item">{{item}}</view>
          </picker-view-column>
          <picker-view-column>
            <view wx:for="{{time_list}}" wx:key="time_list" class="item">{{item}}</view>
          </picker-view-column>
        </picker-view>
      </view>
    </view>
    

    wxss文件:

    .mask {
      position: fixed;
      width: 100%;
      height: 100%;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      display: flex;
      background-color: rgba(0, 0, 0, 0.7);
      z-index: 9999;
      flex-direction: column;
      justify-content: flex-end;
    }
    
    .content {
      display: flex;
      flex-direction: column;
      width: 100%;
      background: white;
      border-top-right-radius: 20rpx;
      border-top-left-radius: 20rpx;
    }
    
    .top {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
      height: 100rpx;
      border-bottom: 1rpx solid #d3cfcf;
    }
    
    .top-text {
      font-size: 30rpx;
      width: 150rpx;
      height: 100rpx;
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
    }
    
    .top-left-color {
      color: #878787;
    }
    
    .top-left-color-hover {
      color: #f1eaea;
    }
    
    .top-right-color {
      color: #1296DB;
    }
    
    .top-right-color-hover {
      color: #82ccf3;
    }
    
    .item {
      width: 100%;
      align-items: center;
      justify-content: center;
      display: flex;
      flex-direction: row;
      font-size: 18px;
    }
    
    Component({
        /**
         * 组件的属性列表
         */
        properties: {
            range: { //可预约的日期范围。默认日期从今天开始,到第range天后为止,这里设为10天
                type: Number,
                value: 10
            },
            start_time: { //开始时间,设为整点
                type: Number,
                value: 8
            },
            step: { //预约时间的步长,设置为30,表示30分钟
                type: Number
            },
            end_time: { //结束时间,设为整点
                type: Number,
                value: 22
            }
        },
    
        /**
         * 组件的初始数据
         */
        data: {
            isShow: false,
            selectDate: "",
            dialogh: 0,
    
            //日期列表和时间列表
            date_list: [],
            time_list: []
        },
        attached: function () {
            let start_day = this.ts_string(new Date().getTime());
            console.log(start_day); //2021-08-31
            console.log(new Date());
            let end_day = this.ts_string(new Date().setDate(new Date().getDate() + this.properties.range))
            //获取日期列表
            let date_list = this.getDiffDate(start_day, end_day);
            //获取时间列表
            let time_list = this.getTimeList(this.properties.start_time, this.properties.end_time, this.properties.step);
            console.log(time_list);
            this.setData({
                // date_time: [date_column, time_column],
                date_list: date_list,
                time_list: time_list,
            })
            //动画
            this.animation = wx.createAnimation({
                duration: 300
            })
            //500rpx转成px
            let dialoghpx = 800 / 750 * wx.getSystemInfoSync().windowWidth
            this.setData({
                dialogh: dialoghpx,
                selectDate: this.data.date_list[0] + this.data.time_list[0]
            })
        },
        methods: {
            getDiffDate(start, end) {
                let startTime = new Date(start);
                let endTime = new Date(end);
                let dateArr = [];
                while ((endTime.getTime() - startTime.getTime()) >= 0) {
                    dateArr.push(this.ts_string(startTime.getTime()));
                    startTime.setDate(startTime.getDate() + 1);
                }
                return dateArr;
            },
            zfill(num, length) {
                return (Array(length).join('0') + num).slice(-length);
            },
            //把日期转换成xxxx-xx-xx的形式
            ts_string(timestamp) {
                let d = new Date(timestamp);
                let day = "";
                switch (d.getDay()) {
                    case 1:
                        day = "周一";
                        break;
                    case 2:
                        day = "周二";
                        break;
                    case 3:
                        day = "周三";
                        break;
                    case 4:
                        day = "周四";
                        break;
                    case 5:
                        day = "周五";
                        break;
                    case 6:
                        day = "周六";
                        break;
                    case 0:
                        day = "周日";
                        break;
                }
                let string = (d.getFullYear()) + "-" +
                    this.zfill((d.getMonth() + 1), 2) + "-" +
                    this.zfill((d.getDate()), 2) + " (" + day + ")"
                return string
            },
            //获取时间区间列表,输入(起始时间,结束时间,步长)
            getTimeList(start, end, step) {
                let start_time = new Date();
                //设置起始时间
                start_time.setHours(start, 0, 0);
                console.log(start_time);
                //设置结束时间
                let end_time = new Date();
                end_time.setHours(end, 0, 0);
                let startG = start_time.getTime(); //起始时间的格林时间
                let endG = end_time.getTime(); //起始时间的格林时间
                let step_ms = step * 60 * 1000;
                let timeArr = [];
                while (startG < endG) {
                    let time = this.timeAdd(startG, step_ms);
                    timeArr.push(time);
                    startG += step_ms;
                }
    
                return timeArr;
            },
            timeAdd(time1, add) {
                var nd = new Date(time1); //创建时间对象
                //获取起始时间的时分秒
                var hh1 = nd.getHours();
                var mm1 = nd.getMinutes();
                if (hh1 <= 9) hh1 = "0" + hh1;
                if (mm1 <= 9) mm1 = "0" + mm1;
                nd = nd.valueOf(); //转换为毫秒数
                nd = nd + Number(add);
                nd = new Date(nd);
                var hh2 = nd.getHours();
                var mm2 = nd.getMinutes();
                if (hh2 <= 9) hh2 = "0" + hh2;
                if (mm2 <= 9) mm2 = "0" + mm2;
                var time = hh1 + ":" + mm1 + "-" + hh2 + ":" + mm2;
                return time; //时间段
            },
            change: function (e) {
                const val = e.detail.value;
                //val[0]表示选择的第一列序号,val[1]表示选择的第二列序号
                let select = this.data.date_list[val[0]] + this.data.time_list[val[1]]
                console.log(select);
                this.setData({
                    selectDate: select
                })
    
            },
            showDialog() {
                this.setData({
                    isShow: true
                })
                //先向下移动dialog高度,然后恢复原位从而形成从下向上弹出效果
                this.animation.translateY(this.data.dialogh).translateY(0).step()
                this.setData({
                    animation: this.animation.export()
                })
            },
            dimsss() {
                //从原位向下移动dailog高度,形成从上向下的收起效果
                this.animation.translateY(this.data.dialogh).step()
                this.setData({
                    animation: this.animation.export()
                })
                //动画结束后蒙层消失
                setTimeout(() => {
                    this.setData({
                        isShow: false
                    })
                }, 300)
            },
            cancel() {
                this.triggerEvent("cancel")
                this.dimsss()
            },
            confirm() {
                this.triggerEvent("confirm", {
                    selectDate: this.data.selectDate
                })
                this.dimsss()
            }
        }
    })
    

    组件的使用

    想在父组件中使用封装好的date-picker组件,先要在父组件的json文件中声明。

    {
      "usingComponents": {
        "date-picker": "../../components/date-picker/date-picker"
      },
    }
    

    如果想实现简单的选择时间段并在页面中显示的功能,父组件代码如下编写即可。
    父组件wxml文件:

    <view class="option" bindtap="timeOpen" style="font-size: 16px;">
          {{selectDate}}
    </view>
    <date-picker id="picker" range="8" step="40" bindconfirm="confirm"></date-picker>
    

    父组件js文件:

    Page({
        data: {
            selectDate: "",
            machineShow: false,
        },
        onLoad: function () {
            this.picker = this.selectComponent("#picker")
        },
        timeOpen() {
            this.picker.showDialog();
        },
        confirm(e) {
            this.setData({
                selectDate: e.detail.selectDate
            })
        },
    })
    

    2.结合vant weapp的date-picker

    自定义的date-picker组件已经可以实现想实现的功能,但自定义的组件样式不够美观。这时,我注意到了小程序可以使用vant的组件库,组件库多列选择器的样式可以自由修改,而且自带样式已经足够美观,所以下面考虑结合vant组件库实现date-picker。

    实现效果

    具体实现

    使用vant weapp的picker组件和popup组件可以更简洁地实现想要的效果,打造自定义的date-picker组件。

    首先需要在编写组件的json文件中导入vant weapp的相应组件

    {
        "component": true,
        "usingComponents": {
            "van-picker": "@vant/weapp/picker/index",
            "van-popup": "@vant/weapp/popup/index"
        }
    }
    

    然后编写date-picker的wxml文件:

    <van-popup round show="{{ isShow }}" bind:close="cancel" position="bottom" custom-style="height: 55%">
      <van-picker show-toolbar columns="{{ date_time_list }}" bind:cancel="cancel" bind:change="change"
        bind:confirm="confirm" />
    </van-popup>
    

    因为van-picker的参数columns接受的是一个对象数组,与picker-view有一定差异,所以需要将date-picker的js文件进行如下更改。
    1.修改data,增加date_time_list

    data: {
            isShow: false,
            selectDate: "",
            dialogh: 0,
    
            //日期列表和时间列表
            date_list: [],
            time_list: [],
            date_time_list: []  //增加的字段
        },
    

    2.修改attached函数

    //增加的内容
    let date_time_list = [{
                    values: date_list
                },
                {
                    values: time_list  
                }
            ];
            this.setData({
                date_list: date_list,
                time_list: time_list,
                date_time_list: date_time_list  //增加的内容
            })
    

    3.修改change函数

    change: function (e) {
                let val = e.detail.value;
                let select = val[0] + val[1];
                this.setData({
                    selectDate: select
                })
    
            },
    
    展开全文
  • 使用Axure RP9实现时间自定义选择框,设置文本框的类型,实现日期自定义选择,下拉选择框实现默认和自定义时间的切换选择
  • 百度指数爬虫, 可以自定义时间段抓取百度指数,非模拟浏览器操作,抓取百度指数的另种思路
  • 笔者有一段时间没有发表关于Android的文章了,关于Android自定义组件笔者有好几篇想跟大家分享的,后期会记录在博客中。本篇博客给大家分享的是自定义一个日期选择器,可以让用户同时选择年月日和当前时间。 先看看...
  • 自定义每隔一段时间自动按下空格键,当然你可根据代码改变你要按的键。
  • jQuery自定义时间段特效拖动设置时间段表单提交 jQuery自定义拖动设置时间段,可以灵活设置天内的任意时段。
  • layui的时间选择自定义选择范围

    千次阅读 2019-09-25 14:58:49
    最近用layui做项目,在时间选择这里,做个笔记留用 **1. 时间和现在的关系 ** 获取当前时间 //年-月-日 function nowDate1(){ var now = new Date(); return now.getFullYear()+"-" + (now.getMonth()+1) +...

    最近用layui做项目,在时间选择这里,做个笔记留用

    1. 时间和现在的关系
    获取当前时间

    //年-月-日
     function nowDate1(){
        var now = new Date();
        return now.getFullYear()+"-" + (now.getMonth()+1) + "-" + now.getDate();
      }
    //时-分-秒
      function nowDate2(){
        var now = new Date();
        return now.getFullYear()+"-" + (now.getMonth()+1) + "-" + now.getDate() + " " + now.getHours()+":"+now.getSeconds()+":"+now.getMinutes();
      }
    

    要求时间从当前时间开始(即最小值是现在)

    laydate.render({
        elem: '#startDate',
        type: 'datetime',
        istime: true,
        istoday: true,
        min:nowDate1()
      });
    

    分别的效果[当前时间:2019-9-25 15:26:16]:
    在这里插入图片描述在这里插入图片描述

    2. 有2个时间,结束时间不能大于开始时间

    js代码

      //授课日期范围
      var startDate=laydate.render({
        elem: '#startDate',
        type: 'datetime',
        istime: true,
        istoday: true,
        done:function(value,date){
          if(value!=""){
            date.month=date.month-1;
            endDate.config.min=date;
          }else{
            endDate.config.min=startDate.config.min;
          }
        },
      });
      var endDate =laydate.render({
        elem: '#endDate',
        type: 'datetime',
        istime: true,
        istoday: true,
        done:function(value,date){
          if(value!=""){
            date.month=date.month-1;
            startDate.config.max=date;
          }else{
            startDate.config.max=endDate.config.max;
          }
        },
      });
    

    在这里插入图片描述

    展开全文
  • 前阵子app里需要用到日历... 就是写自定义日历的,但是看到具体的产品需求以及效果图,我就”嗯,很好……“,不是我不喜欢自定义,而是效果图里面的细节真的是有点多,好了,我们来看看细节: 1、产品需求只显示...

    这里写图片描述
    前阵子app里需要用到日历,效果图如上,做日历我本来是不担心的,因为之前就有写过,比如我之前的文章
    https://blog.csdn.net/danfengw/article/details/72764995
    就是写自定义日历的,但是看到具体的产品需求以及效果图,我就”嗯,很好……“,不是我不喜欢自定义,而是效果图里面的细节真的是有点多,好了,我们来看看细节:
    1、产品需求只显示近3个月,当天时间之前的日期灰色,三个月后当前日期之后的日期也是灰色人,嗯,不明白?那我们来举个例子:今天6月3号,显示3个月,也就是6-8月,6.3号之前是灰色,6.3号是黄色,8.3号之后是灰色。

    2、选择日期,第一次选择是开始日期,第二次选择是结束日期,再次选择则是开始日期(这里你可能会考虑为什么不是我第三次选择日期如果日期比结束日期晚则作为结束日期,比开始日期早则作为开始日期呢?这个逻辑我之前也尝试过,对于用户操作(1)有时候操作不方便(2)关于选择日期会有疑惑,所以才采用了这种相对容易理解的方式)。

    3、选择的开始日期与结束日期分别加了圆圈背景,同时在开始日期与结束日期之间的区域,周六跟周天分别是右半圆跟左半圆背景,其他日期都是矩形背景。

    好了,细节大概是说完了,如果想要理解这篇自定义view建议先去看我上面链接里的自定义日历这篇文章,循序渐进。
    下面再说一下实现思路:recyclerview嵌套,一个水平方向LinearLayoutManager嵌套一个GridLayoutManager说完你大概是理解了吧?

    ps:定制版控件,只适合用来学习思路,如果要用到你自己的项目,还是需要修改的。

    Github 地址

    https://github.com/danfengfirst/DfCalendar

    代码思路

    1、recyclerview嵌套,设置日期
    2、继承textview自定义textview,主要用于修改开始日期与结束日期的圆形背景
    3、继承relativelayout自定义relativelayout,主要用于设置被选中日期的中间时间段。
    4、使用。

    1、CalendarView

    (0)初始化布局

     private void bindView(Context context) {
            View view = LayoutInflater.from(context).inflate(R.layout.appoint_calendarview, this, false);
            title = (TextView) view.findViewById(R.id.calendar_title);
            title.setTextColor(titleColor);
            title.setTextSize(titleSize);
            recyclerView = (RecyclerView) view.findViewById(R.id.calendar_rv);
            linearLayoutManager = new LinearLayoutManager(this.context, LinearLayoutManager.HORIZONTAL, false);
            recyclerView.setLayoutManager(linearLayoutManager);
            PagerSnapHelper snapHelper = new PagerSnapHelper();
            snapHelper.attachToRecyclerView(recyclerView);
            addView(view);
        }

    appoint_calendarview.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:layout_marginTop="@dimen/y42"
        android:orientation="vertical">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal">
    
            <TextView
                android:id="@+id/calendar_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/x60"
                android:text="2018年"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_14"
                android:textStyle="bold" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="@dimen/x20"
                android:layout_toRightOf="@+id/calendar_title"
                android:text="未来三个月可预约时间"
                android:textColor="@color/transparent80_white"
                android:textSize="@dimen/text_size_13"
                android:textStyle="bold" />
        </RelativeLayout>
    
        <LinearLayout
            android:id="@+id/calendar_week_header"
            android:layout_width="match_parent"
            android:layout_height="@dimen/y42"
            android:layout_marginLeft="@dimen/x30"
            android:layout_marginRight="@dimen/x30"
            android:layout_marginTop="@dimen/y34"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            >
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:text=""
                android:textAlignment="center"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_15"
                android:textStyle="bold" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:text=""
                android:textAlignment="center"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_15"
                android:textStyle="bold" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:text=""
                android:textAlignment="center"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_15"
                android:textStyle="bold" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:text=""
                android:textAlignment="center"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_15"
                android:textStyle="bold" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:text=""
                android:textAlignment="center"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_15"
                android:textStyle="bold" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:text=""
                android:textAlignment="center"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_15"
                android:textStyle="bold" />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:text=""
                android:textAlignment="center"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_15"
                android:textStyle="bold" />
        </LinearLayout>
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/calendar_rv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/x30"
            android:layout_marginRight="@dimen/x30"
            android:layout_marginTop="@dimen/y22"></android.support.v7.widget.RecyclerView>
    </LinearLayout>

    (1)设置时间

    //该方法用于设置从服务器获取的时间,如果没有从服务器获取的时间将使用手机本地时间
        private void initTime(Context context, String time) {
            if (!time.equals("")) {
                curDate = DateUtil.strToCalendar(time, CommonConstant.TFORMATE_YMD);
                dateFromServer = DateUtil.strToDate(time, CommonConstant.TFORMATE_YMD);
            } else {
                curDate = Calendar.getInstance();
                dateFromServer = new Date();
            }
        }

    (2)设置3个月时间
    这部分跟上一篇的自定义日历基本一致,但添加了3个月的限制。

      public void renderCalendar(String time) {
            months.clear();
            initTime(context, time);
            for (int i = 0; i < 3; i++) {
                ArrayList<Date> cells = new ArrayList<>();
                if (i != 0) {
                    curDate.add(Calendar.MONTH, 1);//后推一个月
                } else {
                    curDate.add(Calendar.MONTH, 0);//当前月
                }
                Calendar calendar = (Calendar) curDate.clone();
                //将日历设置到当月第一天
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                //获得当月第一天是星期几,如果是星期一则返回1此时1-1=0证明上个月没有多余天数
                int prevDays = calendar.get(Calendar.DAY_OF_WEEK) - 1;
                //将calendar在1号的基础上向前推prevdays天。
                calendar.add(Calendar.DAY_OF_MONTH, -prevDays);
                //最大行数是6*7也就是,1号正好是星期六时的情况
                int maxCellcount = 6 * 7;
                while (cells.size() < maxCellcount) {
                    cells.add(calendar.getTime());
                    //日期后移一天
                    calendar.add(calendar.DAY_OF_MONTH, 1);
                }
                months.add(new CalendarCell(i, cells));
            }
    
            firstMonth = dateFromServer.getMonth();//第一个月
            secondMonth = months.get(1).getCells().get(20).getMonth();//第二个月
            thirdMonth = months.get(2).getCells().get(20).getMonth();//第三个月
            for (int i = 0; i < months.size(); i++) {
                //title格式 201863日
                String title = (months.get(i).getCells().get(20).getYear() + 1900) +
                        context.getResources().getString(R.string.year) +
                        (months.get(i).getCells().get(20).getMonth() + 1) + context.getResources().getString(R.string.month);
                titles.add(title);
            }
            title.setText(titles.get(0));
            //只限定3个月,因此模拟给3个数值即可
            mainAdapter = new MainRvAdapter(R.layout.appoint_calendarview_item, months);
            recyclerView.setAdapter(mainAdapter);
            //recyclerview 的滚动监听
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    title.setText(titles.get(linearLayoutManager.findLastVisibleItemPosition()));
                    super.onScrollStateChanged(recyclerView, newState);
                }
            });
        }
    

    appoint_calendarview_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.RecyclerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/appoint_calendarview_item_rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
    </android.support.v7.widget.RecyclerView>

    (3)设置最外层水平recyclerview的adapter,需要注意注释的几个点

    /**
         * 最外层水平recyclerview的adapter
         */
        private class MainRvAdapter extends BaseQuickAdapter<CalendarCell, BaseViewHolder> {
    
            public MainRvAdapter(int layoutResId, @Nullable List<CalendarCell> data) {
                super(layoutResId, data);
            }
    
            @Override
            protected void convert(BaseViewHolder helper, final CalendarCell item) {
                if (((RecyclerView) helper.getView(R.id.appoint_calendarview_item_rv)).getLayoutManager() == null) {
                    //RecyclerView不能都使用同一个LayoutManager
                    GridLayoutManager manager = new GridLayoutManager(mContext, 7);
                    //recyclerview嵌套高度不固定(wrap_content)时必须setAutoMeasureEnabled(true),否则测量时控件高度为0
                    manager.setAutoMeasureEnabled(true);
                    ((RecyclerView) helper.getView(R.id.appoint_calendarview_item_rv)).setLayoutManager(manager);
                }
                SubRvAdapter subRvAdapter = null;
                if (allAdapters.get(helper.getPosition()) == null) {
                    subRvAdapter = new SubRvAdapter(R.layout.calendar_text_day, item.getCells());
                    allAdapters.put(helper.getPosition(), subRvAdapter);
                    ((RecyclerView) helper.getView(R.id.appoint_calendarview_item_rv)).setAdapter(subRvAdapter);
                } else {
                    subRvAdapter = allAdapters.get(helper.getPosition());
                    ((RecyclerView) helper.getView(R.id.appoint_calendarview_item_rv)).setAdapter(subRvAdapter);
                }
                //item 点击事件响应
                subRvAdapter.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                        Date date = item.getCells().get(position);
                        int day = date.getDate();
                        if (date.getMonth() == secondMonth
                                || (date.getDate() > dateFromServer.getDate() && date.getMonth() == firstMonth)
                                || (date.getDate() <= dateFromServer.getDate() && date.getMonth() == thirdMonth)) {
                            //可点击数据
                            if (isSelectingSTime) {
                                //正在选择开始时间
                                selectSDate(item.getCells().get(position));
                            } else {
                                //正在选择结束时间
                                selectEDate(item.getCells().get(position));
                            }
                        }
                        //更新所有的adapter,比如今天6月,需要更新6、7、8三个月份不同adapter
                        Iterator iterator = allAdapters.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry entry = (Map.Entry) iterator.next();
                            ((SubRvAdapter) entry.getValue()).notifyDataSetChanged();
                        }
                    }
                });
            }
        }

    (4)SubRvAdapter
    这里主要是通过时间进行判断,具体逻辑根据效果图考虑

    private class SubRvAdapter extends BaseQuickAdapter<Date, BaseViewHolder> {
    
            public SubRvAdapter(int layoutResId, @Nullable List<Date> data) {
                super(layoutResId, data);
            }
    
            @Override
            protected void convert(BaseViewHolder helper, Date date) {
                helper.setIsRecyclable(false);//不让recyclerview进行复用,复用会出问题
                ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setEmptyColor(todayEmptyColor);
                ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setFillColor(todayFillColor);
                int day = date.getDate();
                //设置文本
                ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setText(String.valueOf(day));
                //设置颜色
                if (date.getMonth() == secondMonth
                        || (date.getDate() > dateFromServer.getDate() && date.getMonth() == firstMonth)
                        || (date.getDate() <= dateFromServer.getDate() && date.getMonth() == thirdMonth)) {
                    //可选时间
                    ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setTextColor(enableSelectColor);
                } else {
                    //不可选时间
                    ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setTextColor(disableSeletColor);
                }
                if (eDateTime != null && date.getTime() == eDateTime.getTime()) {
                    //结束时间
                    ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).isETime(true);
                    ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isETime(true);
                }
                if (sDateTime != null && date.getTime() == sDateTime.getTime()) {
                    //开始时间
                    if (eDateTime != null) {
                        ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).isSTime(true);
                        ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isSTime(true);
                    } else {
                        ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).isSTime(true);
                    }
                }
                if (sDateTime != null && eDateTime != null && date.getTime() > sDateTime.getTime() && date.getTime() < eDateTime.getTime()) {
                    if (date.getDay() == 6) {//星期六
                        ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isDurationSat(true);
                    } else if (date.getDay() == 0) {//星期日
                        ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isDurationSun(true);
                    } else {
                        helper.getView(R.id.calendar_day_rl).setBackgroundColor(getResources().getColor(R.color.date_duration_bg));
                    }
                }
                if (date.getDate() == dateFromServer.getDate() && date.getMonth() == firstMonth) {
                    ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setToday(true);
                }
            }
        }
    

    SubRvAdapter 需要的对应的布局

    <?xml version="1.0" encoding="utf-8"?>
    <com.df.dfcalendar.widget.CalendarDayRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="@dimen/y66"
        android:gravity="center"
        android:id="@+id/calendar_day_rl"
        android:layout_marginTop="@dimen/y7"
        android:layout_marginBottom="@dimen/y7"
        >
    
        <com.df.dfcalendar.widget.CalendarDayTextView
            android:id="@+id/calendar_day_tv"
            android:layout_width="@dimen/y66"
            android:layout_height="@dimen/y66"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:textColor="@color/white"
            android:text="31"
            android:includeFontPadding="false"
            android:textSize="@dimen/text_size_18"></com.df.dfcalendar.widget.CalendarDayTextView>
    </com.df.dfcalendar.widget.CalendarDayRelativeLayout>
    

    2、CalendarDayTextView

    其实这里画笔只需要一个因为开始时间与结束时间样式一样,但是最开始的时候设计的是颜色不一样,所以就写了2个画笔

    public class CalendarDayTextView extends android.support.v7.widget.AppCompatTextView {
        public boolean isToday;
        private boolean isSTime;
        private boolean isETime;
        private Context context;
    
        public void setEmptyColor(int emptyColor) {
            this.emptyColor = emptyColor;
        }
    
        public void setFillColor(int fillColor) {
            this.fillColor = fillColor;
        }
    
        private int emptyColor = Color.parseColor("#00ff00");
        private int fillColor = Color.parseColor("#00ff00");
    
        private Paint mPaintSTime;
        private Paint mPaintETime;
    
    
    
        public CalendarDayTextView(Context context) {
            super(context);
            initview(context);
        }
    
        public CalendarDayTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initview(context);
        }
    
        private void initview(Context context) {
            this.context=context;
    
            mPaintSTime = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaintSTime.setStyle(Paint.Style.FILL);
            mPaintSTime.setColor(context.getResources().getColor(R.color.date_time_bg));
            mPaintSTime.setStrokeWidth(2);
    
            mPaintETime = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaintETime.setStyle(Paint.Style.FILL);
            mPaintETime.setColor(context.getResources().getColor(R.color.date_time_bg));
            mPaintETime.setStrokeWidth(2);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            //根据当前逻辑开始时间必须先绘制结束时间
            if (isETime) {
                canvas.save();
                //移动到当前控件的中心,以中心为圆点绘制实心圆
                canvas.translate(getWidth() / 2, getHeight() / 2);
                canvas.drawCircle(0, 0, getWidth() / 2 , mPaintETime);
                canvas.restore();
                //此处必须将圆移动回开始位置,否则文本显示会受到影响
                canvas.translate(0, 0);
            }
    
            if (isSTime) {
                canvas.save();
                //移动到当前控件的中心,以中心为圆点绘制实心圆
                canvas.translate(getWidth() / 2, getHeight() / 2);
                canvas.drawCircle(0, 0, getWidth() / 2 , mPaintSTime);
                canvas.restore();
                //此处必须将圆移动回开始位置,否则文本显示会受到影响
                canvas.translate(0, 0);
            }
            super.onDraw(canvas);
        }
    
        public void setToday(boolean today) {
            isToday = today;
            this.setTextColor(context.getResources().getColor(R.color.date_today));
        }
    
        public void isETime(boolean etime) {
            isETime = etime;
            this.setTextColor(context.getResources().getColor(R.color.date_time_tv));
        }
    
        public void isSTime(boolean stime) {
            isSTime = stime;
            this.setTextColor(context.getResources().getColor(R.color.date_time_tv));
        }
    
    }

    3.CalendarDayRelativeLayout

    自定义CalendarDayRelativeLayout,来设置不同背景:(1)长方形背景 (2)星期六(有半圆)(3)星期天(左半圆)

    public class CalendarDayRelativeLayout extends RelativeLayout {
        public CalendarDayRelativeLayout(Context context) {
            this(context, null);
        }
    
        public CalendarDayRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public void isDurationSat(boolean isSaturday) {
            this.setBackground(getResources().getDrawable(R.drawable.appoint_calendar_sat_bg));
        }
    
        public void isDurationSun(boolean isSunday) {
            this.setBackground(getResources().getDrawable(R.drawable.appoint_calendar_sun_bg));
        }
        public void isETime(boolean etime) {
            this.setBackground(getResources().getDrawable(R.mipmap.appoint_calendar_end_bg));}
        public void isSTime(boolean stime) {
            this.setBackground(getResources().getDrawable(R.mipmap.appoint_calendar_start_bg));
        }
    }
    

    4、使用

     mCalendarView.setETimeSelListener(new CalendarView.CalendatEtimSelListener() {
                @Override
                public void onETimeSelect(Date date) {
                    if (date != null) {
                        String etimestr = (date.getYear() + 1900) + getString(R.string.year) + (date.getMonth() + 1) + getString(R.string.month) + date.getDate() + getString(R.string.day);
                        Toast.makeText(getApplicationContext(),"结束时间"+etimestr,Toast.LENGTH_SHORT).show();
                    }
                }
            });
            mCalendarView.setSTimeSelListener(new CalendarView.CalendarSTimeSelListener() {
                @Override
                public void onSTimeSelect(Date date) {
                    if (date != null) {
                        String stimestr = (date.getYear() + 1900) + getString(R.string.year) + (date.getMonth() + 1) + getString(R.string.month) + date.getDate() + getString(R.string.day);
                        Toast.makeText(getApplicationContext(),"开始时间"+stimestr,Toast.LENGTH_SHORT).show();
                    }
                }
            });
    展开全文
  • 1.默认状态(默认选择当前日期的时间段(蓝底背景色代表选中时间段), 2.当前日期之前的时间不可以选择(禁用了点击事件)) 3.当日历上的操作的年份月份小于当前时间的年份月份时禁止点击上月的按钮 选中状态 1....
  • 时间自定义:特定时间段设置 图片 主题代码:只需要引入layui.css和layui.js即可看到效果 注意一点,两个laydate中的format属性里的格式写法,必须不能出现重名的,否则会前者的值会覆盖后者,比如:type为...
  • 使用element日期时间选择器带快捷选项自定义时间: 需要picker-options 和格式化value-format <el-form-item label="关闭时间:" prop="date"> <el-date-picker v-model="date" type="datetimerange" :...
  • 陆续有很多数据粉咨询,如何在 Tableau 中查看固定或者自定义时间段的数据?今天的栗子,我们来分享方法,睹为快吧! 本期《举个栗子》,我们要给大家分享的 Tableau 技巧是:查看固定或自定义时间段的数据。 为...
  • 尽管Android给我们提供了时间选择控件DatePicker和TimePicker(它们的使用方法可以参考我的这篇文章Android之日期时间选择控件DatePicker和TimePicker),但无奈我的项目主色调是土豪金和高级黑,原生的控件用在里面...
  • layui时间选择框,选择时间

    千次阅读 2018-04-20 17:36:09
    在web前端input,时间组件很常用,最近在使用layui的时间组件时,想用时间段,让后面的时间必须大于前面的时间&lt;div class="layui-col-xs8"&gt;  &lt;div class="layui-inline&...
  • NumberPicker自定义时间选择

    千次阅读 2015-06-04 09:25:07
    这两天,项目需求中需要选择时间的功能,主要的需求如下: 1. 显示的时间自定义的,比如 不是顺序的1,2,3,4,5,6,7,8,9, 而是 3,4,6,9 2. 显示的时间内容是 几号,几时,几分 3. 要用Android的原生风格 ...
  • 完全小白就不要看了,容易看迷,涉及到公司的一些东西,里面代码有删减,但是整理一下肯定是能用的,方法抽...这个实现的功能就是echarts x轴自定义时间段显示,自适应分时天月年显示,其他类似根据时间合并也可以用
  • 本文纯属蛋疼,实现一个可以拖动,选择需要播放的时间段,然后播放效果是只播放这一段选中的音乐。 需求:自定义一个Android播放器 可以随意选择需要播放音乐片段 返回选中播放部分的音乐数据 分析: MediaPlayer ...
  • 在CANoe和CANalyzer中的Tools菜单中,提供了个“Logging File Conversion”工具(见下图),将CAN Log文件(*.asc,*.blf…)根据“自定义时间段”截取/分段成多个较小的CAN log文件。 打开“Logging F...
  • 项目需求只选择年月,所以自己做了个很简单的。 默认时间段为1900 - 2099年,可自行调整。 Demo: https://github.com/AllenYL/YLDatePickerView
  • vscode自定义代码

    千次阅读 2018-02-02 21:12:19
     我们就可以自定义开发中常用的代码,节省时间,大大提高开发效率。(注意:创建哪种语言的代码片段就进相应语言的代码片段区域,写js代码就不要把代码写在了php的代码编写区) \r\n...
  • Android自定义DataTimePicker(日期选择器)

    万次阅读 多人点赞 2014-08-23 15:39:05
    Android自定义DataTimePicker(日期选择器) 笔者有一段时间没有发表关于Android的文章了,关于Android自定义组件笔者有好几篇想跟大家分享的,后期会记录在博客中。本篇博客给大家分享的是自定义一个日期选择器,...
  • LocalDate获取自定义日期

    千次阅读 2021-02-22 11:10:51
    * 自定义年月日 * @param year 年 * @param month 月 * @param day 日 * @return LocalDate */ public static LocalDate getLocalDateByYearAndMonthAndDay(int year , int month , int day){ ...
  • 最近参加个开源项目在使用echarts,发现好多人遇到需要自定义X轴时间刻粒度这个问题,为此发篇文章给大家讲解一下1、代码判断xAxis: {type: 'time',splitLine: {show: false},interval: 3600, // 设置x轴时间间隔...
  • DEMO下载 效果图 实现原理 利用微信小程序的picker组件的多列选择器实现! WXML view class=&amp;quot;tui-picker-content&...时间选择器(选择时分)view&amp;gt; pi
  • 因此从这里可以发现,对于IO密集型的应用,我们可以多设置一些线程池中线程的数量,这样就能让在等待IO的这段时间内,线程可以去做其它事,提高并发处理效率。那么这个线程池的数据量是不是可以随便设置呢?当然不是...
  • 前言 有时候我们会有需要在日历上选择一个日期范围的这种需求,先选个开始日期,然后再选结束日期,如酒店...这种日历效果该如何实现呢, 用系统的组件是实现不了的需要自定义日历组件,写自定义view来展示...
  • 如何自定义一个Java注解?

    万次阅读 多人点赞 2020-07-29 23:31:28
    一般官方定义都给的晦涩难懂,其实我们简单理解一下,注解就是标注在类、方法、变量、参数上的种标签,你可以使用JDK内置的注解,也可以自定义注解,通常情况下我们都是使用自定义注解来完成自己的注解功能 ...
  • 学了Android有一段时间了,一直没有时间写博客,趁着周末有点空,就把自己做的一些东西写下来. 一方面锻炼一下自己的写文档的能力,另一方面分享代码的同时也希望能与大家交流一下技术,共同学习,共同进步。因为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 515,524
精华内容 206,209
关键字:

自定义一段时间选择