最近更新时间:2017年10月28日09:42:09
一门技术的出现,必将颠覆人们对开发的全新认识;一门技术的出现,也一定会造成一部分人失业,一部分人获得了很好的工作机会。时代在高速发展,技术也在不断创新,紧跟时代发展潮流,加快学习和实践的速度,是立足于长远发展在当下必须做的事情。
RN技术是用前端的开发思维去开发APP,这门技术的的出现,造成了开发岗位的变动,Android工程师和iOS工程师可以学习这门技术,前端工程师也可以学习这门技术,因此,现在的前端和APP工程的界线没有那么明确了。
在学习和使用RN的过程中,是一项挑战,同时也是十分艰巨的任务,本文记录开发RN过程中的技术细节和实现方案。
1、定时器使用
对于有倒计时显示的页面,当APP不处于前台运行的状态时,定时器会停止计时,退出页面二次进入应用时定时器从刚才退出的时间点开始;但实际需求是倒计时不能停止,因此,需要实时监听APP的状态。
补充:APP的状态分为三种,active-前台运行中、inactive-运行的过渡状态、background-后台运行中
实现方案:
第一步,载入监听APP状态的RN属性;import {AppState} from 'react-native';
第二部,在生命周期函数componentWillMount()中注册监听事件;
componentWillMount(){
AppState.addEventListener('change',this.handleAppStateChange);//‘change’不可改变,属于原生事件名
}
handleAppStateChange = (appState)=>{
if(appState == 'active'){//APP处于前台运行状态}else{//APP处于过渡状态或后台运行中}
}
注意:此处注册的‘change’事件的回调函数的书写方式,由于‘change’事件不属于该组件(页面的)属性事件,而是顶层对象window的属性,因此在handleAppStateChange方法中的this如果不做处理指向的是window,导致this.state和tihs.props或this.otherFunc报错。上面handleAppStateChange方法的实例采用箭头函数的方式,箭头函数中的this总是指向当前执行环境中的对象,也就是该组件(页面)。另一种绑定this指向的方式采用bind函数,如下:
componentWillMount(){
AppState.addEventListener('change',this.handleAppStateChange.bind(this));
}
handleAppStateChange(){
if(appState == 'active'){//APP处于前台运行状态}else{//APP处于过渡状态或后台运行中}
}
第三步,组件卸载时取消事件监听;
componentWillUnmount(){
AppState.removeEventListener('change');
}
备注:监听APP状态的方法一旦注册成功,APPState.currentState也是一个常用的属性
2、拦截(监听)物理返回按键
BackHandler.addEventListener('hardwareBackPress',this.onBackAndroid);
BackHandler.removeEventListener('hardwareBackPress',this.onBackAndroid);
onBackAndroid = ()=>{ ... }
3、退出APP
第一步,载入监听物理返回按键的RN属性;import {BackHandler} from 'react-native';
第二部,在生命周期函数componentWillMount()中注册监听事件;
onBackAndroid = ()=>{
if(!this.confirmExit) {
this.confirmExit = true;
ToastAndroid.show('再按一次退出',ToastAndroid.CENTER,ToastAndroid.SHORT);
this.exitTimer = setTimeout(()=>{this.confirmExit = false;},1000);
}else {
BackHandler.exitApp();
}
return true;//阻止默认行为
}
4、有启动动画的APP
navigate Welcome To HomePage:
componentDidMount(){
this.animateTimer = setTimeout(()=>{this.props.navigation.navigate('HomePage');},2000);
}
5、横屏和竖屏控制
引入第三方组件react-native-orientation:
import Orientation from 'react-native-orientation';
API
Orientation.getInitialOrientation();//'PORTRAIT'-横屏 LANDSCAPE UNKNOWN PORTRAITUPSIDEDOWN
Orientation.lockToPortrait();//设置为竖屏
Orientation.lockToLandscape();//设置为横屏
Orientation.lockToLandscapeLeft();
Orientation.lockToLandscapeRight();
Orientation.unlockAllOrientations();
Orientation.getSpecificOrientation(function(err, specificOrientation);//返回的结果有LANDSCAPE-LEFT LANDSCAPE-RIGHT PORTRAIT UNKNOWN PORTRAITUPSIDEDOWN
Orientation.addOrientationListener(this._orientationDidChange);//添加监听事件
Orientation.removeOrientationListener(this._orientationDidChange);//移除监听事件
_orientationDidChange = (orientation) => {
if (orientation === 'LANDSCAPE') {
// do something with landscape layout
} else {
// do something with portrait layout
}
}
6、获取和监听手机网络状态
获取手机网络状态:
import { NetInfo } from 'react-native';
NetInfo.getConnectionInfo().then((connectionInfo) => {
console.log(JSON.stringify(connectionInfo));
//{"type":"cellular","effectiveType":"4g"}
//{"type":"wifi","effectiveType":"unknown"}
//{"type":"none","effectiveType":"unknown"}
});
NetInfo.fetch().done((reach) => {
//console.log('Initial: ' + reach);// NONE WIFI MOBILE
});
监听手机网络状态,卸载监听事件:
componentDidMount() {
NetInfo.addEventListener('connectionChange', this.handleFirstConnectivityChange);
}
handleFirstConnectivityChange = (reach) => {
console.log(reach);
//{type: "none", effectiveType: "unknown"}
//{type: "wifi", effectiveType: "unknown"}
//{type: "cellular", effectiveType: "4g"}
}
componentWillUnmount() {
console.log('leave')
NetInfo.removeEventListener('connectionChange', this.handleFirstConnectivityChange);
}
6、adb devices连接不上
手机连接不上电脑:
数据线有问题;
重新启动adb服务:adb kill-server adb-start-server
未完,待续...