React Native开发react-native开发React Native学习

react native 自己动手写日历区间选择控件

2018-06-04  本文已影响126人  tomorrow_chen

首先还是看效果图:

image.png

代码复制直接可用



import React, { Component } from 'react'
import { StyleSheet, View, ScrollView, TouchableOpacity, Text, Dimensions } from 'react-native'
import moment from 'moment'

const width = Dimensions.get('window').width
const now = new Date()
export default class App extends Component {

  constructor(props) {
    super(props)
    this.state = {
      nowDate: new Date(),
      showBtn: true,
      startDate: new Date(),
      count: 0,
      endDate: new Date() + 48 * 60 * 60 * 1000
    }
  }

  _onPressButton(date) {
    let { count } = this.state
    let temp = ++count
    if (this.props.range) { // 区间选择
      this.setState({
        count: temp
      })
      if (temp % 2 === 1) { // 第一个日期
        this.setState({
          startDate: date,
          endDate: date,
          showBtn: false
        })
      } else { // 第二个日期
        if (+new Date(this.state.startDate) >= +new Date(date)) { // 第一个日期大于等于第二个日期
          this.setState({
            startDate: date,
            endDate: date,
            count: ++temp,
            showBtn: false
          })
          return
        }
        this.setState({
          endDate: date,
          showBtn: true
        })
      }
      return
    }
    // 单日点击
    this.setState({
      nowDate: date
    }, () => {
      this.callBack()
    })
  }

  callBack() {
    // 回调事件
  }

  render() {
    let { nowDate, showBtn, startDate, endDate } = this.state
    let content = []
    for (let i = 0; i < this.props.monthNum; i++) { // 月数循环
      let date = new Date(now.getFullYear(), now.getMonth() + i, 1);
      let week = date.getDay(); // 当月从星期几开始
      let days = new Date(now.getFullYear(), now.getMonth() + i + 1, 0).getDate();  // 当月的天数
      let dayList = [];
      for (let y = 0; y < week; y++) { // 前面补空占位
        dayList.push(
          <View style={styles.day}>
            <Text style={styles.dayText}></Text>
          </View>
        )
      }

      for (let x = 1; x <= days; x++) { // 循环天数
        let toDay = new Date(now.getFullYear(), now.getMonth() + i, x); // 今天
        let g = this.props.goliday[moment(toDay).format('YYYY-MM-DD')];
        if (!g) { // 节假日
          g = x;
        }
        let node = <View style={styles.day}><TouchableOpacity onPress={this._onPressButton.bind(this, toDay)} activeOpacity={0.5}><Text style={[styles.dayText, { color: '#000' }]}>{g}</Text></TouchableOpacity></View>
        if (i == 0 && x < now.getDate()) { // 今天以前的日期置灰 ,无事件
          if ((week + x) % 7 == 1 || (week + x) % 7 == 0) { // 周末 蓝色
            node = <View style={styles.day}><Text style={[styles.dayText, { color: '#105eae' }]}>{g}</Text></View>
          } else {
            node = <View style={styles.day}><Text style={[styles.dayText, { color: '#999' }]}>{g}</Text></View>
          }
        } else if (i == 0 && x == now.getDate()) { // 今天
          node = <View style={styles.day}><TouchableOpacity onPress={this._onPressButton.bind(this, toDay)} activeOpacity={0.5}><Text style={[styles.dayText, { color: '#000' }]}>今天</Text></TouchableOpacity></View>
        } else if ((week + x) % 7 == 1 || (week + x) % 7 == 0) { // 周末 蓝色
          node = <View style={styles.day}><TouchableOpacity onPress={this._onPressButton.bind(this, toDay)} activeOpacity={0.5}><Text style={[styles.dayText, { color: '#105eae' }]}>{g}</Text></TouchableOpacity></View>
        }
        if (!this.props.range) { // 单日
          if (moment(toDay).format('YYYY-MM-DD') === moment(nowDate).format('YYYY-MM-DD')) { // 选中日期
            node = <View style={[styles.day, styles.curr]}><TouchableOpacity onPress={this._onPressButton.bind(this, toDay)} activeOpacity={0.5}><Text style={[styles.dayText, { color: '#fff' }]}>{g}</Text></TouchableOpacity></View>
          }
        } else { // 区间

          if (+new Date(toDay) > +new Date(startDate) && +new Date(toDay) < +new Date(endDate)) {
            node = <View style={[styles.day, styles.range]}><TouchableOpacity onPress={this._onPressButton.bind(this, toDay)} activeOpacity={0.5}><Text style={[styles.dayText, { color: '#fff' }]}>{g}</Text></TouchableOpacity></View>
          }
          if (moment(toDay).format('YYYY-MM-DD') === moment(endDate).format('YYYY-MM-DD')) { // 选中日期
            node = <View style={[styles.day, styles.curr]}><TouchableOpacity onPress={this._onPressButton.bind(this, toDay)} activeOpacity={0.5}><Text style={[styles.startdayText, { color: '#fff', paddingTop: ((width / 7) - 20) * 0.2, paddingBottom: ((width / 7) - 20) * 0.1 }]}>{g}</Text><Text style={[styles.start, { paddingTop: ((width / 7) - 20) * 0.1, paddingBottom: ((width / 7) - 20) * 0.2 }]}>离店</Text></TouchableOpacity></View>
          }
          if (moment(toDay).format('YYYY-MM-DD') === moment(startDate).format('YYYY-MM-DD')) { // 选中日期
            node = <View style={[styles.day, styles.curr]}><TouchableOpacity onPress={this._onPressButton.bind(this, toDay)} activeOpacity={0.5}><Text style={[styles.startdayText, { color: '#fff', paddingTop: ((width / 7) - 20) * 0.2, paddingBottom: ((width / 7) - 20) * 0.1 }]}>{g}</Text><Text style={[styles.start, { paddingTop: ((width / 7) - 20) * 0.1, paddingBottom: ((width / 7) - 20) * 0.2 }]}>入住</Text></TouchableOpacity></View>
          }
        }
        dayList.push(node)
      }
      content.push( // 添加节点
        <View>
          <View style={styles.head}><Text>{moment(date).format('YYYY年MM月')}</Text></View>
          <View style={styles.content}>
            {dayList}
          </View>
        </View>
      )
    }

    return (
      <View style={styles.container}>
        <View style={styles.weekContainer}>
          <Text style={[styles.weekText]}>日</Text>
          <Text style={styles.weekText}>一</Text>
          <Text style={styles.weekText}>二</Text>
          <Text style={styles.weekText}>三</Text>
          <Text style={styles.weekText}>四</Text>
          <Text style={styles.weekText}>五</Text>
          <Text style={[styles.weekText]}>六</Text>
        </View>
        <ScrollView
          showsHorizontalScrollIndicator={false}
          showsVerticalScrollIndicator={false}    // 隐藏垂直指示器
        >
          {content}
        </ScrollView>
        {
          showBtn ?
            <TouchableOpacity onPress={this.callBack.bind(this)} style={styles.btn}><Text style={{ color: '#fff' }}>确定</Text></TouchableOpacity> : null
        }
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    paddingTop: 20,
    flex: 1,
    backgroundColor: '#fff'
  },
  weekContainer: {
    width: width,
    height: 35,
    backgroundColor: '#105eae',
    flexDirection: 'row',
    alignItems: 'center'
  },
  weekText: {
    width: width / 7,
    lineHeight: 35,
    textAlign: 'center',
    color: '#fff'
  },
  content: {
    flexDirection: 'row',
    alignItems: 'center',
    flexWrap: 'wrap'
  },
  day: {
    width: width / 7 - 0.1,
  },
  dayText: {
    textAlign: 'center',
    fontSize: 16,
    paddingVertical: ((width / 7) - 20) * 0.5
  },
  startdayText: {
    textAlign: 'center',
    fontSize: 14
  },
  curr: {
    backgroundColor: '#105eae',
  },
  range: {
    backgroundColor: '#6CAFF5'
  },
  head: {
    alignItems: 'center',
    margin: 10
  },
  start: {
    color: '#fff',
    textAlign: 'center',
    fontSize: 14
  },
  btn: {
    width: width,
    height: 45,
    backgroundColor: '#105eae',
    alignItems: 'center',
    alignSelf: 'center',
    justifyContent: 'center'
  }
})

App.defaultProps = {
  monthNum: 6, // 显示的月数
  range: true,
  goliday: { // 节假日在这里添加
    '2018-04-05': '清明',
    '2018-05-01': '劳动',
    '2018-06-18': '端午',
    '2018-09-24': '中秋',
    '2018-10-01': '国庆'
  }
}
上一篇下一篇

猜你喜欢

热点阅读