import React, { Component } from 'react';
import {
Text,
View,
StyleSheet,
TouchableOpacity,
Image,
} from 'react-native';
const weeks = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
class Calender extends Component {
constructor(props) {
super(props);
this.state = {
itemsArr: new Array(42), // 创建一个长度42的数组
year: new Date().getFullYear(), // 年
month: new Date().getMonth() + 1, // 月
date: new Date().getDate(), // 日
week: new Date().getDay(), // 周几
monthStartIndex: 0, // 本月第一天是在itemsArr的下标值
startX: 0, // 开始拖拽时的offsetX
}
}
// 本月有多少天
get monthDays() {
return new Date(this.state.year, this.state.month, 0).getDate();
}
// 上个月有多少天
get lastMonthDays() {
return new Date(this.state.year, this.state.month - 1, 0).getDate();
}
// 本月第一天是周几
get weekStart() {
return new Date(this.state.year, this.state.month - 1, 1).getDay();
}
componentDidMount() {
this.fillDate();
}
fillDate = () => {
const { year, month } = this.state;
console.log(month);
// 这个月天数遍历
let arr = new Array(42);
for (let i = 1; i <= this.monthDays; i++) {
arr[this.weekStart + i - 1] = { date: i, month, year };
}
// 上个月天数遍历
let j = 0;
for (let i = this.weekStart - 1; i >= 0; i--) {
arr[i] = { date: this.lastMonthDays - j, month: month !== 1 ? month - 1 : 12, year: month !== 1 ? year : year - 1 };
j++;
}
// 计算出本月第一天是在itemsArr的下标值
let nowMonthStartIndex = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i].date === 1) {
nowMonthStartIndex = i;
break;
}
}
// 填充下个月
if (arr.length % 7 !== 0 || arr.includes(undefined)) {
let k = 1;
// 下个月开始的位置
let nextMonthStartIndex = nowMonthStartIndex + this.monthDays;
// 下个月的出现的天数
// let nextMonthLength = itemsArr.length % 7 !== 0
// ? 7 - itemsArr.length % 7
// : itemsArr.length - nextMonthStartIndex;
let nextMonthLength = arr.length - nextMonthStartIndex;
for (let i = 0; i < nextMonthLength; i++) {
arr[i + nextMonthStartIndex] = { date: k, month: month !== 12 ? month + 1 : 1, year: month !== 12 ? year : year +1 };
k++;
}
}
this.setState({
itemsArr: [...arr],
monthStartIndex: nowMonthStartIndex,
});
}
isToday = item => {
const isNowYear = new Date().getFullYear() === item.year ? true : false;
const isNowMonth = new Date().getMonth() + 1 === item.month ? true : false;
const isNowDay = new Date().getDate() === item.date ? true : false;
return isNowYear && isNowMonth && isNowDay;
}
// 获取样式
getDayStyle = (item, n) => {
const { date, monthStartIndex } = this.state;
const obj = this.isToday(item) ? {
borderWidth: 1,
borderStyle: 'solid',
borderColor: '#6495ed',
} : {};
if (date === n - monthStartIndex + 1 && n >= monthStartIndex && n < monthStartIndex + this.monthDays) {
return this.isToday(item) ? {
backgroundColor: '#6495ed',
...obj,
} : {
// backgroundColor: '#6495ed',
backgroundColor: 'red',
borderRadius: 8,
};
} else if (this.isToday(item)) {
return obj;
}
}
getTextStyle = n => {
const { date, monthStartIndex } = this.state;
if (date === n - monthStartIndex + 1 && n >= monthStartIndex && n < monthStartIndex + this.monthDays) {
return {
color: '#ffffff',
};
} else if (n < monthStartIndex || n > (this.monthDays + monthStartIndex - 1)) {
return {
color: '#a9a9a9',
};
}
}
onClick = (item, index) => {
const { year, month, monthStartIndex } = this.state;
const obj = {};
if (index < monthStartIndex) {
if (month > 1) {
obj.month = month - 1;
} else {
obj.year = year - 1;
obj.month = 12;
}
} else if (index >= monthStartIndex + this.monthDays) {
if (month < 12) {
obj.month = month +1;
} else {
obj.year = year + 1;
obj.month = 1;
}
}
this.setState({
...obj,
date: item.date,
}, () => {
this.fillDate();
});
}
onResponderGrant = e => {
console.log(e.nativeEvent.locationX)
this.setState({
startX: e.nativeEvent.locationX,
});
}
onResponderRelease = e => {
const { startX, month, year } = this.state;
const obj = {};
const diff = e.nativeEvent.locationX - startX;
if (diff > 60) {
if (month !== 1) {
obj.month = month - 1;
} else {
obj.month = 12;
obj.year = year - 1;
}
} else if (diff < -60) {
if (month !== 12) {
obj.month = month + 1;
} else {
obj.month = 1;
obj.year = year + 1;
}
}
if (obj.month) {
this.setState({
...obj,
date: 1,
}, () => {
this.fillDate();
});
}
}
onBackToDaY = () => {
this.setState({
year: new Date().getFullYear(),
month: new Date().getMonth() + 1,
date: new Date().getDate(),
});
}
handleArrowLeft = () => {
const { month, year } = this.state;
const obj = {};
if (month !== 1) {
obj.month = month - 1;
} else {
obj.month = 12;
obj.year = year - 1;
}
this.setState({
...obj,
date: 1,
}, () => {
this.fillDate();
});
}
handleArrowright = () => {
const { month, year } = this.state;
const obj = {};
if (month !== 12) {
obj.month = month + 1;
} else {
obj.month = 1;
obj.year = year + 1;
}
this.setState({
...obj,
date: 1,
}, () => {
this.fillDate();
});
}
render() {
const { itemsArr, year, month } = this.state;
return (
<View style={styles.calender}>
<View style={styles.header}>
<View style={styles.calenderHeader}>
<TouchableOpacity onPress={this.handleArrowLeft}>
<Image source={require('./arrow-left.png')} />
</TouchableOpacity>
<Text style={{ paddingLeft: 10, paddingRight: 7 }}>{`${year}年${month}月`}</Text>
<TouchableOpacity onPress={this.handleArrowright}>
<Image source={require('./arrow-right.png')} />
</TouchableOpacity>
</View>
{/* <TouchableOpacity onPress={this.onBackToDaY}>
<Text>回今天</Text>
</TouchableOpacity> */}
</View>
<View style={styles.main}>
<View style={styles.mainHeader}>
{weeks.map((one, i) => (
<View style={{ flex: 1 }} key={`${one}_${i}`}>
<Text style={{ textAlign: 'center' }}>{one}</Text>
</View>
))}
</View>
<View
// onStartShouldSetResponder={() => true}
// onResponderGrant={this.onResponderGrant}
// onResponderMove={onResponderMove}
// onResponderReject={onResponderReject}
// onResponderRelease={this.onResponderRelease}
accessible={true}
style={styles.contentWrap}
>
<View
style={styles.mainContent}
onPress={() => console.log(222)}
>
{itemsArr.map((one, i) => (
<View style={styles.contentDay} key={`${one}_${i}`} onPress={() => console.log(33)}>
<TouchableOpacity onPress={() => this.onClick(one, i)}>
<View style={[styles.itemStyle, this.getDayStyle(one, i)]}>
<Text style={[styles.textStyle, this.getTextStyle(i)]}>{one.date}</Text>
</View>
</TouchableOpacity>
</View>
))}
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
calender: {
paddingHorizontal: 16,
paddingVertical: 10,
backgroundColor: '#ffffff'
},
header: {
justifyContent: 'center',
alignItems: 'center',
paddingBottom: 10,
fontSize: 16,
fontWeight: '700',
},
calenderHeader: {
alignItems: 'center',
flexDirection: 'row',
},
mainHeader: {
height: 40,
borderTopColor: '#ccc',
borderTopWidth: 1,
flexDirection: 'row',
paddingTop: 10,
},
contentWrap: {
width: '100%',
},
mainContent: {
flexDirection: 'row',
flexWrap: 'wrap',
},
contentDay: {
width: '14.28%',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 5,
},
itemStyle: {
width: 30,
height: 30,
borderRadius: 8,
},
textStyle: {
textAlign: 'center',
lineHeight: 30,
color: 'black',
borderWidth: 0,
},
});
export default Calender;