我开始为我的应用程序使用react native日历。我在其中一个屏幕上使用了议程。但是,选择日期时有一个奇怪的问题。我已经设置了pastScrollRange和futureScrollRange。问题是,只要我从日历的第一个月中选择任何日期,就会向我显示下个月的最后一周。例如,如果2017年1月是日历的第一个月,则在选择任何日期后,它将向我显示2017年2月的最后一周。类似地,当我从日历中的最后一个月中选择任何日期时,它将显示该月的第一周。我一直在试图找出解决方案,但似乎无济于事。任何指导将不胜感激。
请查看以下屏幕截图。在下面的屏幕截图中,2017年12月是日历的第一个月,而2021年12月是日历的最后一个月份。
这是我的代码。
import React, { useState, useEffect } from "react";
import { View, Text, Image, TouchableOpacity, SafeAreaView, StyleSheet, Platform } from "react-native";
import { Agenda } from "react-native-calendars";
import Toast from "react-native-simple-toast";
import moment from "moment";
import "../../../Utils/Globals";
import { SERVICES_FOR_DATE_URL, CLIENT_ID_KEY } from "../../../Config/Routes";
import { requestData } from "../../../Api/ApiRequests";
import ServiceEvent from "./ServiceEvent";
//import { checkLocationPermission, requestLocationPermission, getDistance } from "../../../Location/LocationManager";
import Geolocation from "react-native-geolocation-service";
import Icon from "react-native-vector-icons/FontAwesome";
let watchId = "";
const ServicesCalendarScreen = (props) => {
//let date = moment();
//date = moment().format("MMMM YYYY");
//date = moment().month() + moment().year();
//Toast.show(""+date, Toast.LONG);
//events state hook for selected day events
const [events, setEvents] = useState(null);
//set selected month and year
const [date, setDate] = useState(moment().format("MMMM YYYY"));
//hook for setting selected date to pass to onRefresh prop of agenda to refresh the selected date contents
const [dateToRefresh, setDateToRefresh] = useState(moment().format("YYYY-MM-DD"));
const getSelectedDayEvents = (date) => {
let serviceDate = moment(date);
serviceDate = serviceDate.format("DD/MM/YYYY");
const data = { ClientId : CLIENT_ID, ServiceDate : serviceDate };
//returned result with fetch api
requestData(PROVIDER_URL + SERVICES_FOR_DATE_URL, data).then((result) => {
console.log(result);
if (result.status == "Successful") {
if (result.data != "") {
//changing the received result object so that calendar can view the event on selected date
let modifiedData = { [date] : result.data };
setEvents(modifiedData);
console.log(modifiedData);
//to change the month and year on top of agenda
//setDate(moment(date).format("MMMM YYYY"));
}
else {
let modifiedData = { [date] : result.data };
setEvents(modifiedData);
}
}
else {
Toast.show(result.message ? result.message : result, Toast.SHORT);
}
})
.catch((error) => {
console.log(error);
});
}
//this condition is implemented when we need to refresh data when we appear from another screen
if (typeof props.navigation.state.params !== "undefined") {
const refreshData = props.navigation.state.params.refreshData;
const selectedDate = props.navigation.state.params.selectedDate;
props.navigation.state.params = undefined;
let date = selectedDate.replace(/\//g, "-");
date = moment(selectedDate, "DD-MM-YYYY").format("YYYY-MM-DD");
//date = date.format("YYYY-MM-DD");
getSelectedDayEvents(date);
// if (refreshData) {
// let currentDate = moment();
// currentDate = currentDate.format("YYYY-MM-DD");
// getSelectedDayEvents(currentDate);
// }
}
//getting the service date to populate the selected day calendar events
useEffect(() => {
let currentDate = moment();
currentDate = currentDate.format("YYYY-MM-DD");
getSelectedDayEvents(currentDate);
// if (Platform.OS === "android") {
// //checking the status if user has location permission enabled, if not then show the permission popup to user
// requestLocationPermission().then((status) => {
// console.log(status);
// if (status === "granted") {
// //getting location response through promise from another file
// // const watchID = await getPosition().then((position) => {
// // console.log(position);
// // })
// // .catch((error) => {
// // console.log(error);
// // });
// // console.log(watchID);
// //options for location
// const options = {
// enableHighAccuracy: true,
// timeout : 15000,
// interval : 30000
// };
// //for iOS only
// if (Platform.OS === "ios")
// setRNConfiguration(options);
// //continuously get location after every 30 seconds
// watchID = Geolocation.watchPosition((position) => {
// const currentLat = position.coords.latitude;
// const currentLng = position.coords.longitude;
// const residentLat = -37.901639;
// const residentLng = 145.054707;
// Toast.show("Location Updated", Toast.LONG);
// getDistance(currentLat, currentLng, residentLat, residentLng).then((data) => {
// console.log(data);
// })
// .catch((error) => {
// console.log(error);
// });
// },
// (error) => {
// console.log(error);
// },
// options);
// }
// else {
// console.log("No permission allowed for accessing location");
// }
// })
// .catch((error) => {
// console.log(error);
// });
// }
// else {
// }
}, []);
// useEffect(() => {
// checkLocationPermission().then((permissionStatus) => {
// switch (permissionStatus) {
// case "granted":
// break;
// case "denied":
// break;
// case "blocked":
// break;
// case "unavailable":
// break;
// }
// })
// .catch((error) => {
// console.log(error);
// });
// });
return (
<View style = {{ flex : 1 }}>
<View style = { styles.dateViewStyle }>
<TouchableOpacity
style = { styles.dateButtonStyle }
//onPress = {() => openCalendar ? setOpenCalendar(false) : setOpenCalendar(true) }
>
<Text style = { styles.dateStyle }>{ date }</Text>
</TouchableOpacity>
</View>
<Agenda items = { events } /*shouldOpenCalendar = { openCalendar }*/
// Enable or disable scrolling of calendar list
scrollEnabled = { false }
// Max amount of months allowed to scroll to the past. Default = 50
pastScrollRange = { 12 }
// Max amount of months allowed to scroll to the future. Default = 50
futureScrollRange = { 12 }
// callback that gets called when items for a certain month should be loaded (month became visible)
// loadItemsForMonth={(month) => {
// let currentDate = moment();
// currentDate = currentDate.format("YYYY-MM-DD");
// if (currentDate == month.dateString) {
// getSelectedDayEvents(month.dateString);
// }
// console.log(currentDate);
// }
// }
// callback that fires when the calendar is opened or closed
onCalendarToggled = {(calendarOpened) => calendarOpened ? setDate("") : null }
// callback that gets called on day press
onDayPress={(day)=>{
getSelectedDayEvents(day.dateString);
//to change the month and year on top of agenda
setDate(moment(day.dateString).format("MMMM YYYY"));
//set the date in case onRefresh is executed
setDateToRefresh(day.dateString);
}
}
// callback that gets called when day changes while scrolling agenda list
onDayChange={(day)=>{
console.log('day changed')
}
}
// specify how each item should be rendered in agenda
renderItem={(item, firstItemInDay) => {
return (<ServiceEvent eventDetails = { item } navigation = { props.navigation } />);
}
}
// specify how each date should be rendered. day can be undefined if the item is not first in that day.
// renderDay={(day, item) => {
// return (<View><Text>Text</Text></View>);
// }
// }
// specify how empty date content with no items should be rendered
renderEmptyDate = {() => {
return (
<View style = { styles.viewStyle }>
<Icon name = "exclamation-triangle" size = { 30 } color = "#2079B3"/>
<Text style = { styles.textStyle }>No services on this date</Text>
</View>
);
}}
// specify how agenda knob should look like
renderKnob={() => {
return (
<TouchableOpacity /*onPress = {() => openCalendar ? setOpenCalendar(false) : setOpenCalendar(true)}*/>
<Icon name = "chevron-down" size = { 20 } color = "#2079B3" />
</TouchableOpacity>
);
}}
// specify what should be rendered instead of ActivityIndicator
// renderEmptyData = {() => {
// return (<View><Text>No service on this date</Text></View>);
// }}
// specify your item comparison function for increased performance
rowHasChanged={(r1, r2) => {return r1 !== r2;}}
// By default, agenda dates are marked if they have at least one item, but you can override this if needed
// markedDates={{
// '2019-11-22': {selected: true, marked: true},
// '2019-11-23': {marked: true},
// '2019-11-24': {disabled: true}
// }}
// If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly.
onRefresh={() => getSelectedDayEvents(dateToRefresh)}
//styling agenda calendar view
theme = {{
textDayFontSize: 16,
textMonthFontSize: 20,
textDayHeaderFontSize: 16
}}
/>
</View>
);
}
const styles = StyleSheet.create({
dateViewStyle : {
flexDirection : "row",
justifyContent : "center",
height : "auto"
},
dateStyle : {
color : "#2079B3",
fontSize : 18,
padding : 10,
margin : 5,
borderRadius: 5
},
viewStyle : {
flexDirection : "row",
justifyContent : "center",
padding : 5,
marginTop : 30,
height : 50
},
textStyle : {
fontSize : 18,
margin : 5
}
});
export default ServicesCalendarScreen;
答案 0 :(得分:0)
您可以做两件事:
更新版本“ react-native-calendars”:“ 1.220.0” 修复了日历折叠时标题的怪异滚动行为。
您可以为主题设置样式,就像我分别为iOS和Android处理的情况一样:
distributionUrl=https://privateRepo/gradle-5.0-bin.zip
例如:
'stylesheet.calendar.header': { week: { marginTop: Platform.OS=='ios'?6:2, flexDirection: 'row', justifyContent: 'space-between' } }
我的议程组件供参考:
<Agenda
theme={{
'stylesheet.calendar.header': { week: { marginTop: Platform.OS=='ios'?6:2, flexDirection: 'row', justifyContent: 'space-between' } }
}}>
答案 1 :(得分:0)
我发现这是因为最后一个日历页面仍在堆栈导航中,并且高度没有正确计算。 因此,我从堆栈导航中删除了所有数据(您可以找到完全相同的日历页面并将其删除)。 之后,导航到该页面,一切正常。
import {NavigationActions, StackActions} from 'react-navigation';
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'name of calendar component' })],
});
navigation.dispatch(resetAction)
不需要任何样式上的改变。