美文网首页React Native开发Android开发经验谈Android开发
React-Native 简单实现日历样式的签到记录

React-Native 简单实现日历样式的签到记录

作者: zsgnaw | 来源:发表于2019-03-26 17:11 被阅读55次
    image.png
    import React from "react";
    import {StyleSheet, Text, View} from 'react-native';
    import type {ViewStyleProp} from "react-native/Libraries/StyleSheet/StyleSheet";
    
    type Props = {
        viewStyles: ?ViewStyleProp,
        nowDate?: ?Date,
    };
    
    export default class SignInView extends React.Component<Props> {
    
        constructor(props) {
            super(props);
    
            this.state = {
                weeks: [],
                days: [],
            }
    
            this.lastDay = null
            this.nowDate = this.props.nowDate ? this.props.nowDate : new Date()
    
        }
    
        componentDidMount() {
            // 先获取最后一天
            const day = this.nowDate
            this.lastDay = new Date(day.getFullYear(), day.getMonth() + 1, 0)
    
            const w = this._getMonthWeek()
            const weekTemp = []
    
            for (let i = 1; i <= w; i++) {
                weekTemp.push(i)
            }
    
            this.setState({
                weeks: weekTemp
            })
    
            this._fetch()
        }
    
        // 获取当月有几周 周一开始
        _getMonthWeek = () => {
            const first = this._getFirstDay()
            // 获取第一周有几天
            const firstDays = 8 - first // 7 - f + 1
            return Math.ceil((this.lastDay.getDate() - firstDays) / 7) + 1
        }
    
        // 获取当月第一天是星期几  周一开始
        _getFirstDay = () => {
            const day = this.nowDate
            day.setDate(1)
            return day.getDay() === 0 ? 7 : day.getDay()
        }
    
        // 模拟请求数据
        _fetch = async () => {
            const signDay = []
            setTimeout(() => {
                signDay.push(1)
                signDay.push(5)
                signDay.push(6)
                signDay.push(7)
                signDay.push(10)
    
                this.setState({
                    days: signDay
                })
            }, 2000);
    
        }
    
        render() {
    
            const first = this._getFirstDay() - 1
            const {viewStyles} = this.props
    
            return (
                <View style={[{padding: 10, backgroundColor: '#fff'}, viewStyles]}>
                    <View style={styles.content}>
                        <Text style={styles.title}>一</Text>
                        <Text style={styles.title}>二</Text>
                        <Text style={styles.title}>三</Text>
                        <Text style={styles.title}>四</Text>
                        <Text style={styles.title}>五</Text>
                        <Text style={styles.title}>六</Text>
                        <Text style={styles.title}>日</Text>
                    </View>
                    {this.state.weeks.map((week) => (
                        <View style={styles.content}>
                            {this._getDayItem(7 * week - 6 - first)}
                            {this._getDayItem(7 * week - 5 - first)}
                            {this._getDayItem(7 * week - 4 - first)}
                            {this._getDayItem(7 * week - 3 - first)}
                            {this._getDayItem(7 * week - 2 - first)}
                            {this._getDayItem(7 * week - 1 - first)}
                            {this._getDayItem(7 * week - first)}
                        </View>
                    ))}
                </View>
            )
        }
    
        _getDayItem(day) {
            const l = this.lastDay.getDate()
            if (this.state.days.indexOf(day) < 0) {
                return <Text style={styles.item}>{day > 0 && day <= l ? day : ''}</Text>
            }
            return (
                <View style={styles.itemChoosed}>
                    <Text style={styles.textChoosed}>{day}</Text>
                </View>
            )
        }
    }
    
    const styles = StyleSheet.create({
        content: {
            flexDirection: 'row',
            paddingVertical: 10,
        },
        title: {
            flex: 1,
            textAlign: 'center',
            fontSize: 14,
            color: '#000',
        },
        item: {
            flex: 1,
            textAlign: 'center',
            fontSize: 12,
        },
        itemChoosed: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
        },
        textChoosed: {
            textAlign: 'center',
            marginTop: 2,
            fontSize: 11,
            backgroundColor: '#108AED',
            borderRadius: 9,
            width: 18,
            height: 18,
            color: '#fff',
        },
    })
    

    简单使用

    import React, {Component} from 'react';
    import {StyleSheet, Text, View} from 'react-native';
    import SignInView from "./src";
    
    type Props = {};
    export default class App extends Component<Props> {
        render() {
            return (
                <View style={styles.container}>
                    <Text style={styles.welcome}>Welcome to React Native!</Text>
                    <SignInView viewStyles={{width: '90%', height: 'auto'}} nowDate={new Date(2018, 3, 8)}/>
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: 'grey',
        },
        welcome: {
            fontSize: 20,
            textAlign: 'center',
            margin: 10,
        },
    });
    

    相关文章

      网友评论

        本文标题:React-Native 简单实现日历样式的签到记录

        本文链接:https://www.haomeiwen.com/subject/zmrnvqtx.html