React native 后退按钮反应本机退出应用程序
我已经在我的主屏幕上的react native应用程序中设置了android后退按钮退出应用程序功能。但当我在其他屏幕上按下android后退按钮时,它也会被调用React native 后退按钮反应本机退出应用程序,react-native,react-native-android,React Native,React Native Android,我已经在我的主屏幕上的react native应用程序中设置了android后退按钮退出应用程序功能。但当我在其他屏幕上按下android后退按钮时,它也会被调用 componentDidMount() { if (Platform.OS == "android") { BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
componentDidMount() {
if (Platform.OS == "android") {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
this._setupGoogleSignin();
this._getUserDetails();
const { navigate } = this.props.navigation;
console.log("object url is", this.state.postsArray[0].url);
}
handleBackButton = () => {
Alert.alert(
'Exit App',
'Exiting the application?', [{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel'
}, {
text: 'OK',
onPress: () => BackHandler.exitApp()
}, ], {
cancelable: false
}
)
return true;
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
如果在导航到其他屏幕时,或在卸载
主屏幕时,主屏幕仍处于安装状态,如果不删除EventListener,则仍将调用它
您应该在导航或卸载时清除EventListener
onButtonPress = () => {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
// then navigate
navigate('NewScreen');
}
handleBackButton = () => {
Alert.alert(
'Exit App',
'Exiting the application?', [{
text: 'Cancel',
onPress: () = > console.log('Cancel Pressed'),
style: 'cancel'
}, {
text: 'OK',
onPress: () = > BackHandler.exitApp()
}, ], {
cancelable: false
}
)
return true;
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
Guyz请理解这可能不仅仅是react native的问题。与firebase集成时要小心。最近的firebase版本存在在react原生应用程序中集成后退按钮的问题!!请将firebase版本降级为firebase版本@5.0.3,然后重新检查是否工作!我也有同样的问题,担心了好几天。我最终降级到@5.0.3版本,现在后退按钮工作得非常好!如果仍然面临此问题,您可能会降级到较低版本。我们可以在主应用程序容器中为didfocus添加订阅。我们可以添加逻辑以检查是否有使用静态变量点击的按钮
import { Alert, BackHandler, ToastAndroid } from 'react-native';
import { StackActions } from 'react-navigation';
import { Toast } from 'native-base';
// common statless class variable.
let backHandlerClickCount = 0;
class App extends React.Component {
constructor(props) {
super(props);
// add listener to didFocus
this._didFocusSubscription = props.navigation.addListener('didFocus', payload =>
BackHandler.addEventListener('hardwareBackPress', () => this.onBackButtonPressAndroid(payload)));
}
// remove listener on unmount
componentWillUnmount() {
if (this._didFocusSubscription) {
this._didFocusSubscription.remove();
}
}
onBackButtonPressAndroid = () => {
const shortToast = message => {
// ToastAndroid.showWithGravityAndOffset(
// message,
// ToastAndroid.SHORT,
// ToastAndroid.BOTTOM,
// 25,
// 50
// );
// ios & android
Toast.show({
text: message,
type: 'warning',
position: 'top',
duration: 3000,
});
}
const {
clickedPosition
} = this.state;
backHandlerClickCount += 1;
if ((clickedPosition !== 1)) {
if ((backHandlerClickCount < 2)) {
shortToast('Press again to quit the application!');
} else {
BackHandler.exitApp();
}
}
// timeout for fade and exit
setTimeout(() => {
backHandlerClickCount = 0;
}, 2000);
if (((clickedPosition === 1) &&
(this.props.navigation.isFocused()))) {
Alert.alert(
'Exit Application',
'Do you want to quit application?', [{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel'
}, {
text: 'OK',
onPress: () => BackHandler.exitApp()
}], {
cancelable: false
}
);
} else {
this.props.navigation.dispatch(StackActions.pop({
n: 1
}));
}
return true;
}
}
从'react native'导入{Alert,BackHandler,ToastAndroid};
从“react navigation”导入{StackActions};
从'native base'导入{Toast};
//公共无状态类变量。
让backHandlerClickCount=0;
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
//将侦听器添加到didFocus
这是._didFocusSubscription=props.navigation.addListener('didFocus',payload=>
BackHandler.addEventListener('hardwareBackPress',()=>this.onBackButtonPressAndroid(有效负载));
}
//卸载时删除侦听器
组件将卸载(){
如果(这是一项重点认购){
此._didFocusSubscription.remove();
}
}
onBackButtonPressAndroid=()=>{
const shortToast=消息=>{
//用重力和偏移量来显示(
//信息,
//ToastAndroid.SHORT,
//ToastAndroid.BOTTOM,
// 25,
// 50
// );
//ios和android
吐司,表演({
文本:消息,
键入:“警告”,
位置:'顶部',
时长:3000,
});
}
常数{
点击位置
}=本州;
backHandlerClickCount+=1;
如果((单击位置!==1)){
如果((backHandlerClickCount<2)){
shortToast('再次按退出应用程序!');
}否则{
BackHandler.exitApp();
}
}
//淡入淡出超时
设置超时(()=>{
backHandlerClickCount=0;
}, 2000);
如果((单击位置===1)&&
(this.props.navigation.isFocused())){
警惕,警惕(
“退出应用程序”,
'是否要退出应用程序?'[{
文本:“取消”,
onPress:()=>console.log('Cancel Pressed'),
样式:“取消”
}, {
文本:“OK”,
onPress:()=>BackHandler.exitApp()
}], {
可取消:false
}
);
}否则{
this.props.navigation.dispatch(StackActions.pop({
n:1
}));
}
返回true;
}
}
如果您不希望警报消息出现在其他组件/屏幕中,而只出现在一个特定组件/屏幕中,您可以按照此操作
import { withNavigationFocus } from 'react-navigation';
class TestComponent extends Component {
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
handleBackButton = () => {
if (this.props.isFocused) {
Alert.alert(
'Exit App',
'Exiting the application?',
[
{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel'
},
{
text: 'OK',
onPress: () => BackHandler.exitApp()
}
],
{
cancelable: false
}
);
return true;
}
};
}
export default withNavigationFocus(TestComponent );
显示警报消息的BackHandler将仅在TestComponent中工作您始终可以动态修改BackHandler.addEventListener
的回调函数基于当前场景的内容(使用react native router flux
可以轻松实现)
完整的要点可以在这里找到:如果你想双击返回按钮退出应用程序
import React, {useEffect} from 'react';
import {BackHandler} from 'react-native';
import {Provider} from 'react-redux';
import Toast from 'react-native-root-toast';
let backHandlerClickCount = 0;
const App = () => {
useEffect(() => {
// back handle exit app
BackHandler.addEventListener('hardwareBackPress', backButtonHandler);
return () => {
BackHandler.removeEventListener('hardwareBackPress', backButtonHandler);
};
}, []);
const backButtonHandler = () => {
const shortToast = message => {
Toast.show(message, {
duration: Toast.durations.LONG,
position: Toast.positions.BOTTOM,
});
}
let backHandlerClickCount;
backHandlerClickCount += 1;
if ((backHandlerClickCount < 2)) {
shortToast('Press again to quit the application');
} else {
BackHandler.exitApp();
}
// timeout for fade and exit
setTimeout(() => {
backHandlerClickCount = 0;
}, 1000);
return true;
}
return (
<Provider store={store}>
....
</Provider>
);
};
export default App;
import React,{useffect}来自“React”;
从“react native”导入{BackHandler};
从'react redux'导入{Provider};
从“react native root Toast”导入Toast;
让backHandlerClickCount=0;
常量应用=()=>{
useffect(()=>{
//后把手退出应用程序
addEventListener('hardwareBackPress',backButtonHandler);
return()=>{
removeEventListener('hardwareBackPress',backButtonHandler);
};
}, []);
常量backButtonHandler=()=>{
const shortToast=消息=>{
祝酒词{
持续时间:Toast.durations.LONG,
位置:Toast.positions.BOTTOM,
});
}
让BackHandler点击计数;
backHandlerClickCount+=1;
如果((backHandlerClickCount<2)){
shortToast('再次按退出应用程序');
}否则{
BackHandler.exitApp();
}
//淡入淡出超时
设置超时(()=>{
backHandlerClickCount=0;
}, 1000);
返回true;
}
返回(
....
);
};
导出默认应用程序;
只是添加到其他答案中
如果您使用的是“@react navigation/native”
,则在backButton上设置eventListner将起作用,即使您已导航到子屏幕。要克服此问题,请将eventListner设置在焦点
上,而不是使用componentDidMount()
并在屏幕上发生模糊
事件时将其删除
}我在这个问题上也遇到了问题,但我设法用一种非常简单的方法解决了它。我使用的是react导航4.4.1
import React from 'react';
import { BackHandler, ToastAndroid} from 'react-native';
export default class LoginScreen extends React.Component {
state = {
canBeClosed: false
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
handleBackButton = () => {
if (this.props.navigation.isFocused()) {
if (this.state.canBeClosed)
return this.state.canBeClosed = false;
else {
setTimeout(() => { this.state.canBeClosed = false }, 3000);
ToastAndroid.show("Press Again To Exit !", ToastAndroid.SHORT);
return this.state.canBeClosed = true
}
}
};
//some code
}
@请用您尝试过的代码更新您的问题。主屏幕是我打开应用程序时打开的主屏幕。所以我想在点击硬件后退按钮时退出应用程序。我已经更新了code@ParasWatts正如我在回答中所说的,我相信主屏幕并没有卸载
import React, {useEffect} from 'react';
import {BackHandler} from 'react-native';
import {Provider} from 'react-redux';
import Toast from 'react-native-root-toast';
let backHandlerClickCount = 0;
const App = () => {
useEffect(() => {
// back handle exit app
BackHandler.addEventListener('hardwareBackPress', backButtonHandler);
return () => {
BackHandler.removeEventListener('hardwareBackPress', backButtonHandler);
};
}, []);
const backButtonHandler = () => {
const shortToast = message => {
Toast.show(message, {
duration: Toast.durations.LONG,
position: Toast.positions.BOTTOM,
});
}
let backHandlerClickCount;
backHandlerClickCount += 1;
if ((backHandlerClickCount < 2)) {
shortToast('Press again to quit the application');
} else {
BackHandler.exitApp();
}
// timeout for fade and exit
setTimeout(() => {
backHandlerClickCount = 0;
}, 1000);
return true;
}
return (
<Provider store={store}>
....
</Provider>
);
};
export default App;
export class sampleScreen extends Component {
constructor(props) {
super(props);
this.state = {
foo: '',
bar: '',
};
this._unsubscribeSiFocus = this.props.navigation.addListener('focus', e => {
console.warn('focus signIn');
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
});
this._unsubscribeSiBlur = this.props.navigation.addListener('blur', e => {
console.warn('blur signIn');
BackHandler.removeEventListener(
'hardwareBackPress',
this.handleBackButton,
);
});
onButtonPress = () => {
BackHandler.removeEventListener(
'hardwareBackPress',
this.handleBackButton,
);
};
}
handleBackButton = () => {
Alert.alert(
'Exit App',
'Exiting the application?',
[{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel',
},
{
text: 'OK',
onPress: () => BackHandler.exitApp(),
},
], {
cancelable: false,
},
);
return true;
};
componentDidMount() {
// BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
this._unsubscribeSiFocus();
this._unsubscribeSiBlur();
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
import React from 'react';
import { BackHandler, ToastAndroid} from 'react-native';
export default class LoginScreen extends React.Component {
state = {
canBeClosed: false
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
handleBackButton = () => {
if (this.props.navigation.isFocused()) {
if (this.state.canBeClosed)
return this.state.canBeClosed = false;
else {
setTimeout(() => { this.state.canBeClosed = false }, 3000);
ToastAndroid.show("Press Again To Exit !", ToastAndroid.SHORT);
return this.state.canBeClosed = true
}
}
};
//some code
}