【问题标题】:Preventing hardware back button android for React Native防止 React Native 的硬件后退按钮 android
【发布时间】:2016-10-20 04:06:48
【问题描述】:

我想阻止用户返回上一个屏幕。所以我添加了代码,但这不起作用。有什么解决方案吗?看到弹出警报,但“return false”不起作用。

componentDidMount() {
   BackAndroid.addEventListener('hardwareBackPress', () => {
     Alert.alert("alert","alert")

      this.props.navigator.pop();

       return false;
   });

【问题讨论】:

  • 您的问题几乎没有上下文。请浏览How to Ask 部分并改进您的帖子。谢谢。
  • 尝试删除this.props.navigator.pop();

标签: android react-native


【解决方案1】:

如果你想禁用默认的后退按钮行为,你需要return true

这是一个示例组件,它将阻止用户返回上一个屏幕。

import React, {Component,} from 'react';
import {
    View,
    Text,
    BackHandler,
    ToastAndroid,
} from 'react-native';

class BackButtonDemo extends Component {
    componentDidMount() {
        BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
    }

    componentWillUnmount() {
        BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
    }

    handleBackButton() {
        ToastAndroid.show('Back button is pressed', ToastAndroid.SHORT);
        return true;
    }

    render() {
        return (
            <View>
                <Text>Back button example</Text>
            </View>
        );
    }
}

module.exports = BackButtonDemo;

注意:

同时从您的解决方案中删除 this.props.navigator.pop();

Navigatorpop 函数会将用户带到Navigator 呈现的上一个屏幕。

【讨论】:

  • BackAndroid 现已弃用。您应该使用 BackHandler。它使用相同的事件侦听器方法,因此变化不大。
  • 我怎样才能让它为单个屏幕配置?
  • 我只想禁用硬件和虚拟后退按钮按下,但保持标题后退按钮从反应导航工作。这个答案也很好用吗?或者这个desable all back touch events (header and Android Button, virtual and phisic)?
  • return true 是关键
【解决方案2】:

Shiny 使用 react hooks 的新实现:

import React, {Component, useEffect} from 'react';
import {
    View,
    Text,
    BackHandler,
} from 'react-native';

const LogInView = () => {

    useEffect(() => {
      const backHandler = BackHandler.addEventListener('hardwareBackPress', () => true)
      return () => backHandler.remove()
    }, [])

    return (
        <View>
            <Text>Back button example</Text>
        </View>
    );
}

export default LoginView

【讨论】:

  • 这段代码完美运行,但有没有办法将它普遍应用于整个应用程序?我已经在App.js 文件中添加了这段代码,但由于某种原因它并没有在全球范围内应用。我必须将它分别添加到每个屏幕。
  • 对不起@sj_959,我从未见过此评论。你可以把它放在一个帮助文件中并从那里导入吗?虽然现在参加聚会可能有点晚了......
  • 是的,应该这样做@Rambatino。谢谢。
  • 第一个 () =&gt; true 和第二个 () =&gt; true 没有相同的引用。因此,实际上您永远不会删除添加的事件侦听器。
  • 您能否详细说明一下和/或链接到文档?
【解决方案3】:

我通过在 App.js 中添加此代码来禁用整个应用程序的后退按钮 (android)

componentDidMount() {
  BackAndroid.addEventListener('hardwareBackPress', this.handleBackButton);
}

componentWillUnmount() {
  BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButton);
}

handleBackButton() {
  return true;
}

别忘了导入 BackAndroid

import {BackAndroid} from 'react-native'

【讨论】:

  • 谢谢!这有效,但我收到警告消息,然后我在你的答案中使用了“BackHandler”而不是“BackAndroid”。然后工作正常,没有任何警告。
  • 我认为这不会经常起作用,因为订阅是以相反的顺序调用的,所以如果有另一个代码(或 3rd 方库)订阅了其他事件,那么该事件将被触发在后面的新闻中。因此,即使您在根级别订阅了您的事件,它也不会每次都有效。这里说明:facebook.github.io/react-native/docs/backhandler
  • 你的应该是不同版本的 react native 造成的。也许在发布此答案时,它仍在使用“BackAndroid”,但随后他们计划更改为“BackHandler”。至于现在,我在 react native 0.60,“BackAndroid”完全消失了,我必须使用“BackHandler”
【解决方案4】:

只需返回 true 即可尝试禁用后退按钮

import {BackAndroid} from 'react-native';

componentWillMount() {
   BackAndroid.addEventListener('hardwareBackPress', () => {return true});
} 

【讨论】:

  • BackAndroid 现已弃用
【解决方案5】:

使用来自 react native 的 BackHandler 对我有用。只需将此行包含在您的 ComponentWillMount 中:

BackHandler.addEventListener('hardwareBackPress', function() {return true})

它将禁用安卓设备上的后退按钮。

【讨论】:

    【解决方案6】:

    只是为了在使用react-navigation时给你一个完整的答案:

    如果您使用 react-navigation,请将以下内容放在 RootNavigation 类而不是 App.js 中,以禁用整个应用程序的后退按钮。

    import { BackHandler } from 'react-native';
    
    componentDidMount() {
        BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressed);
    }
    
    componentWillUnmount() {
        BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressed);
    }
    
    onBackButtonPressed() {
        return true;
    }
    

    【讨论】:

      【解决方案7】:

      如果你使用 react-natigation 那么你需要使用BackHandler 而不是BackAndroid

      import { BackHandler } from 'react-native';
      
      // code
      
      componentDidMount() {
        BackHandler.addEventListener('backPress');
      }
      
      // some more code
      
      componentWillUnmount() {
        BackHandler.removeEventListener('backPress');
      }
      

      【讨论】:

      • 是的,BackHandler,因为 BackAndroid 已被弃用
      【解决方案8】:

      所以当每个人都在使用 react-native 的 Backhandler 时,我尝试使用 react-navigation 来防止返回处理程序。 这对我有用。 如果您只是想阻止返回而不向用户显示或提醒任何内容。

      React.useEffect(() => {
              navigation.addListener('beforeRemove', (e) => {
                  e.preventDefault();
              });
          }, [navigation]);
      

      你可以把这段代码放在你的函数组件中。

      用例:

      在用户注册时用户注册并去确认 屏幕上的代码,所以我们不希望他回来你可以使用这个代码 瞬间。

      【讨论】:

        【解决方案9】:

        禁用模块反应导航的后退按钮,使用钩子useFocusEffect

        const hardwareBackPressCustom = useCallback(() => {
                return true;
            }, []);
        
        useFocusEffect(() => {
            BackHandler.addEventListener('hardwareBackPress', hardwareBackPressCustom)
            return () => {
              BackHandler.removeEventListener('hardwareBackPress', hardwareBackPressCustom)
            };
          }, []);
        

        【讨论】:

          【解决方案10】:

          对我来说,这是解决方案:

          import React, { useEffect } from 'react'
          import { View } from 'react-native'
          
          function Home({ navigation }) {
              useEffect(() =>
                  navigation.addListener('beforeRemove', (e) => {
                      e.preventDefault();
                      return
                  }),
                  [navigation]
              );
          
          
              return (
                  <View>
                      
                      ...
          
                  </View>
              )
          }
          
          export default Home
          

          你可以在docs看到一个例子

          【讨论】:

            【解决方案11】:

            RN docs 中看到的只是版本 6.x 的更新

              function ScreenWithCustomBackBehavior() {
              // ...
            
              useFocusEffect(
                React.useCallback(() => {
                  const onBackPress = () => {
                    if (isSelectionModeEnabled()) {
                      disableSelectionMode();
                      return true;
                    } else {
                      return false;
                    }
                  };
            
                  BackHandler.addEventListener('hardwareBackPress', onBackPress);
            
                  return () =>
                    BackHandler.removeEventListener('hardwareBackPress', onBackPress);
                }, [isSelectionModeEnabled, disableSelectionMode])
              );
            
              // ...
            }
            

            或者作为一个钩子

            import {useNavigation} from '@react-navigation/native';
            import {useEffect, useState, useCallback} from 'react';
            
            export const usePreventGoBack = () => {
              const navigation = useNavigation();
              const [allow, setAllow] = useState(false);
            
              const beforeRemoveListener = useCallback(
                e => {
                  if (allow) {
                    return;
                  }
                  e.preventDefault();
                },
                [allow],
              );
            
              useEffect(() => {
                const unsub = navigation.addListener('beforeRemove', beforeRemoveListener);
                return () => {
                  unsub();
                };
              }, [navigation, beforeRemoveListener, allow]);
            
              return (cb: () => void) => {
                setAllow(true);
                setTimeout(() => {
                  cb();
                });
              };
            };
            

            绕过

             const continuePressed = () => {
                allowBackButton(() => {
                  navigation.popToTop();
                });
              };
            

            【讨论】:

              【解决方案12】:

              硬件后退按钮的 OnClick OnBackPressed 回调被调用

              您可以在 onBackPressed 回调中删除超级声明。

               @Override
                  public void onBackPressed() {
              
                  }
              

              【讨论】:

              • 那是android java代码,这是一个react native问题。
              猜你喜欢
              • 2017-01-19
              • 2022-08-20
              • 2017-11-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-10-06
              • 2019-08-11
              相关资源
              最近更新 更多