React Native学习之日期时间
日期、时间选择器:
- Android 采用api的形式实现
- iOS 采用组件的形式实现
DatePickerAndroid与TimePickerAndroid
DatePickerAndroid
打开一个标准的Android日期选择器的对话框
static open(options: Object)
可选的options对象的key值如下:
date
(Date对象或毫秒时间戳) - 默认显示的日期minDate
(Date对象或毫秒时间戳) - 可选的最小日期maxDate
(Date对象或毫秒时间戳) - 可选的最大日期
在用户选好日期后返回一个Promise,回调参数为一个对象,其中包含有action, year, month (0-11), day。如果用户取消了对话框,Promise仍然会执行,返回的action为DatePickerAndroid.dismissedAction,其他几项参数则为undefined。所以请在使用其他值之前务必先检查action的值。
注意:当Android手机操作系统低于5.0时,设置最小和最大日期会导致api异常,最好不要设置,而是在用户选择完成后再进行检查;api中的open函数打开的界面是系统的界面,不能设置其任何显示样式,如何手机显示不同是因为系统被厂商深度定制。
TimePickerAndroid
打开一个标准的Android时间选择器的对话框
static open(options: Object)
可选的options对象的key值如下:
hour
(0-23) - 要显示的小时,默认为当前时间minute
(0-59) - 要显示的分钟,默认为当前时间is24Hour
(boolean) - 如果设为true,则选择器会使用24小时制;如果设为false,则会额外显示AM/PM的选项;如果不设定,则采取当前地区的默认设置
在用户选好时间后返回一个Promise,回调参数为一个对象,其中包含有action, hour (0-23), minute (0-59)。如果用户取消了对话框,Promise仍然会执行,返回的action为TimePickerAndroid.dismissedAction
,其他几项参数则为undefined。所以请在使用其他值之前务必先检查action的值。一般用TimePickerAndroid.timeSetAction
的取反来判断
注意:
is24Hour
在某些手机上不会产生作用,用户没有选择时间是因为按下了返回键或取消键;同样的api中的Open打开的是系统的界面。
实现
index.android.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Navigator,
ScrollView,
Image,
AsyncStorage,
TouchableOpacity,
View,
Platform,
BackAndroid,
ToastAndroid,
} from 'react-native';
import DatePicker from './DatePicker.js';
import TimePicker from './TimePicker.js';
class RNAPP extends Component {
render() {
let defaultName = 'Home';
let defaultComponent = Home;
return (
<Navigator
initialRoute = {{ name: defaultName, component: defaultComponent }}
ref = "navigator"
//配置场景
configureScene = {
(route) => {
//这个是页面之间跳转时候的动画,具体有哪些?可以看这个目录下,有源代码的: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js
return Navigator.SceneConfigs.VerticalDownSwipeJump;
}
}
renderScene = {
(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}
}
/>
);
}
componentWillMount() {
if (Platform.OS === 'android') {
BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid);
//BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid, true);
}
}
componentWillUnmount() {
if (Platform.OS === 'android') {
BackAndroid.removeEventListener('hardwareBackPress', this.onBackAndroid);
}
}
onBackAndroid = () => {
const navigator = this.refs.navigator;
const routers = navigator.getCurrentRoutes();
console.log('当前路由长度:' + routers.length);
if (routers.length > 1) {
navigator.pop();
return true; //接管默认行为
} else {
if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
//最近2秒内按过back键,可以退出应用。
return false;
}
this.lastBackPressed = Date.now();
ToastAndroid.show('再按一次退出应用', ToastAndroid.SHORT);
return true;
}
return false; //默认行为
};
}
class Home extends Component {
render() {
return (
<View style={styles.container}>
<View style={{marginTop: 10}}>
<Text onPress={this.goDatePicker.bind(this) } style={styles.btn}>日期选择</Text>
<Text onPress={this.goTimePicker.bind(this) } style={styles.btn}>时间选择</Text>
</View>
<View style={styles.container} ></View>
<Text style={styles.author}>Powered by RNAPP.CC</Text>
</View>
);
}
goDatePicker() {
const { navigator } = this.props;
if (navigator) {
navigator.push({
name: 'DatePicker',
component: DatePicker,
})
}
}
goTimePicker() {
const { navigator } = this.props;
if (navigator) {
navigator.push({
name: 'TimePicker',
component: TimePicker,
})
}
}
}
const styles = StyleSheet.create({
btn: {
justifyContent: 'flex-start',
backgroundColor: '#FF7200',
height: 33,
textAlign: 'center',
textAlignVertical: 'center',
color: '#fff',
marginLeft: 10,
marginRight: 10,
lineHeight: 24,
marginTop: 20,
fontSize: 18,
},
author: {
justifyContent: 'flex-end',
alignItems: 'center',
marginBottom: 10,
textAlign: 'center',
},
container: {
flex: 1,
},
});
AppRegistry.registerComponent('RNAPP', () => RNAPP);
DatePicker.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
DatePickerAndroid,
View
} from 'react-native';
export default class DatePicker extends Component {
constructor(props) {
super(props);
this.state = {
result: 'default',
};
}
componentWillMount() {
let self = this;
let today = new Date();
let theMinDate = new Date(2015, 1, 1);
let theMaxDate = new Date(2025, 1, 1);
let option = {
date: today,
minDate: theMinDate,
maxDate: theMaxDate,
};
DatePickerAndroid.open(option).then(
result => {
if (result.action === DatePickerAndroid.dismissedAction) {
self.setState({
result: '用户没有选择日期',
});
} else {
self.setState({
result: '用户选择:' + result.year + '年' + (result.month + 1) + '月' + result.day + '日',
});
}
}
).catch(
error => {
console.log('错误:' + error);
}
);
}
render() {
return (
<View style={styles.flex}>
<View style={[styles.flex, styles.center]}>
<Text style={{ fontSize: 18, color: 'red' }}>{this.state.result}</Text>
</View>
<Text style={styles.author}>Powered by RNAPP.CC</Text>
</View>
);
}
}
const styles = StyleSheet.create({
flex: {
flex: 1,
},
center: {
justifyContent: 'center',
alignItems: 'center',
},
author: {
justifyContent: 'flex-end',
alignItems: 'center',
marginBottom: 10,
textAlign: 'center',
},
});
TimePicker.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
TimePickerAndroid,
View
} from 'react-native';
export default class TimePicker extends Component {
constructor(props) {
super(props);
this.state = {
result: 'default',
};
}
componentWillMount() {
let self = this;
let theHour = 18;
let theMinute = 55;
let is24Hour = false;
let option = {
//hour: theHour,
//minute: theMinute,
is24Hour: is24Hour,
};
TimePickerAndroid.open(option).then(
result => {
if (result.action !== TimePickerAndroid.timeSetAction) {
self.setState({
result: '用户没有选择时间',
});
} else {
self.setState({
result: '用户选择:' + result.hour + '小时' + result.minute + '分钟',
});
}
}
).catch(
error => {
self.setState({
result: '错误:' + error,
});
}
);
}
render() {
return (
<View style={styles.flex}>
<View style={[styles.flex, styles.center]}>
<Text style={{ fontSize: 18, color: 'red' }}>{this.state.result}</Text>
</View>
<Text style={styles.author}>Powered by RNAPP.CC</Text>
</View>
);
}
}
const styles = StyleSheet.create({
flex: {
flex: 1,
},
center: {
justifyContent: 'center',
alignItems: 'center',
},
author: {
justifyContent: 'flex-end',
alignItems: 'center',
marginBottom: 10,
textAlign: 'center',
},
});
IOS日期时间组件DatePickerIOS
日期时间选择器在iOS中是以组件的形式存在,DatePickerIOS支持View组件的所有属性,可以设置其宽度、高度、位置等。
这是一个受约束的(Controlled)组件,所以必须监听onDateChange回调函数并且及时更新date属性来使得组件更新,否则用户的修改会立刻被撤销来确保当前显示值和props.date一致。
除了View组件的属性,DatePickerIOS组件还支持如下属性:
- `date:当前被选中的日期和时间,Date类型
maximumDate
minimumDate
minuteInterval
(1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30):用来设置可选的最小分钟单位mode
('date', 'time', 'datetime'):选择器模式timeZoneOffsetInMinutes
:以分钟为单位的时区时间差。默认情况下,选择器会选择设备的默认时区。通过此参数,可以指定一个时区。举个例子,要使用北京时间(东八区),可以传递8 * 60。
DatePickerIOS组件的回调方法:
onDateChange
:当用户修改日期或时间时调用此回调函数。唯一的参数是一个Date对象,表示新的日期和时间(也就是用户选择的)
注意:必须要把一个日期类型的状态机变量赋值给DatePickerIOS组件的date属性,并且在用户操作DatePickerIOS组件修改后,用onDateChange回调的新的date去更新对应的状态机变量,否则会出现用户使用DatePickerIOS组件修改改了时间,几秒钟后,DatePickerIOS组件又回到了原来的时间的情况。
警告的解决方案:
- warning:Invalid prop 'date' of type 'Number'
- warning:Required prop 'onDateChange' was not specified
这是一个bug,升级React Native 到0.28及以上版本即可,如果不想升级,可以照这个修改:
修改文件:node_modules/react-native/Libraries/Components/DatePicker/DatePickerIOS.ios.js
参考:https://github.com/facebook/react-native/commit/cec913e7ce05d26181ab4d46e2e41d72acdfb87d
参考:http://stackoverflow.com/questions/35764088/prop-issues-with-datepickerios-in-react-native
范例:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
DatePickerIOS,
} from 'react-native';
class RNAPP extends Component {
constructor(props){
super(props);
this.state={
date1: new Date(),
date2: new Date(),
date3: new Date(),
};
}
//const timeZoneOffsetInHours = (-1)*(new Date()).getTimezoneOffset()/60;
onDateChange1(date){
this.setState({
date1:date,
});
}
onDateChange2(date){
this.setState({
date2:date,
});
}
onDateChange3(date){
this.setState({
date3:date,
});
}
render() {
return (
<View style={styles.container}>
<DatePickerIOS style={styles.flex} date={this.state.date1} mode="datetime" onDateChange={date=>this.onDateChange1(date)} />
<DatePickerIOS style={styles.flex} date={this.state.date2} mode="time" onDateChange={date=>this.onDateChange2(date)} />
<DatePickerIOS style={styles.flex} date={this.state.date3} mode="date" onDateChange={date=>this.onDateChange3(date)} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
flex:{
flex:1,
},
item:{
marginTop:10,
marginLeft:5,
marginRight:5,
height:30,
borderWidth:1,
padding:6,
borderColor:'#ddd',
}
});
AppRegistry.registerComponent('RNAPP', () => RNAPP);
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/react-native-learning-date-and-time/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论