React Native-无法捕获硬件后退按钮单击事件

时间:2018-07-24 05:19:18

标签: react-native react-native-navigation wix-react-native-navigation

我以前常通过Wix 本机导航进行应用导航。但是它不能正常工作。通过我的应用程序对用户进行身份验证后,成功导航到主屏幕,但是问题是当我按下android后退按钮时,它将再次导航到登录屏幕。我需要避免这种情况。我该怎么做?最后尝试从应用程序完全退出。但是它也不能正常工作。我尝试了一些解决方案,但是这些解决方案对我没有用。在这里,我附上了一些我尝试过的解决方案。

尝试01

componentWillUnmount() {
    if (Platform.OS === 'android') return
    BackHandler.removeEventListener('hardwareBackPress')
  }

  componentWillMount() {
    Alert.alert(
      "Warning!",
      "one")
    if (Platform.OS === 'android' && this.props.login)
      BackHandler.addEventListener('hardwareBackPress', () => {
        Alert.alert(
          "Warning!",
          "two")
        return true
      })
  }

尝试01:此功能正常运行,但这不能解决问题。

尝试02

constructor(props) {
super(props);
this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
}

onNavigatorEvent(event) {
    switch (event.id) {
        case "willAppear":
            this.backHandler = BackHandler.addEventListener(
            "hardwareBackPress",
            this.handleBackPress,
            Alert.alert(
                event.id,
                "willAppear")
            );
            break;
        case "willDisappear":
            this.backPressed = 0;
            Alert.alert(
              "Warning!",
              "willDisappear")
            this.backHandler.remove();
            break;
          default:
            break;
        }
    }

handleBackPress = () => {
console.log("handleBackPress");
    if (this.backPressed && this.backPressed > 0) {
        if (this.props.login) {
            console.log("login");
            RNExitApp.exitApp();
        } else {
            console.log("root");
            this.props.navigator.popToRoot({ animated: false });
            return false;
        }
    }
}

尝试02:在此尝试中,“ onNavigatorEvent(事件)”正常运行。但是第一次(第一次用户登录到系统,直到保存会话之前)不起作用,但是此后任何时间此功能都起作用。

这是完整的代码。

LoginScreen.js
this.props.navigator.push({
      screen: "auxxa.LandingScreen",
      passProps: { login: true },
      overrideBackPress: true,
      navigatorStyle: {
        navBarHidden: true
      }
    });

LandingScreen.js

constructor(props) {
    super(props);

    this.state = {
      size: { width, height },
      tileData: null,
      isLoading: true,
      user_id: null,
      refetching: false,
      access_token: null
    };
    //  this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
  }

  onNavigatorEvent(event) {
    switch (event.id) {
      case "willAppear":
        this.backHandler = BackHandler.addEventListener(
          "hardwareBackPress",
          this.handleBackPress,
          Alert.alert(
            event.id,
            "willAppear")
        );
        break;
      case "willDisappear":
        this.backPressed = 0;
        Alert.alert(
          "Warning!",
          "willDisappear")
        this.backHandler.remove();
        break;
      default:
        break;
    }
  }

  handleBackPress = () => {
    console.log("handleBackPress");
    if (this.backPressed && this.backPressed > 0) {
      if (this.props.login) {
        console.log("login");
        // RNExitApp.exitApp();
      } else {
        console.log("root");
        this.props.navigator.popToRoot({ animated: false });
        return false;
      }
    }

    this.backPressed = 1;
    this.props.navigator.showSnackbar({
      text: "Press one more time to exit",
      duration: "long"
    });
    return true;
  };

  componentWillUnmount() {
    if (Platform.OS === 'android') return
    BackHandler.removeEventListener('hardwareBackPress')
  }

  componentWillMount() {
    Alert.alert(
      "Warning!",
      "one")
    if (Platform.OS === 'android' && this.props.login)
      BackHandler.addEventListener('hardwareBackPress', () => {
        Alert.alert(
          "Warning!",
          "two")
        return true
      })
  }

  //Firebase initialization

  componentDidMount() {
    NetInfo.isConnected.addEventListener("change", this.handleConnectionChange);
    // if network connected this will change the state --
    NetInfo.isConnected.fetch().done(isConnected => {
      if (isConnected) {
        this.setState({ status: isConnected });
        this._retrieveData();
      }
      else {
        this.setState({ refetching: false })
        // Alert.alert(
        //   "Warning!",
        //   "Please check your network connection.",
        //   [
        //     {
        //       text: "Cancel",
        //       onPress: () => console.log("Cancel Pressed"),
        //       style: "cancel"
        //     },
        //     { text: "OK", onPress: () => console.log("OK Pressed") }
        //   ],
        //   { cancelable: false }
        // end here
        // );
      }
    });

    //Push Notification implementation

    if (Platform.OS == "android") {
      FCM.requestPermissions();
      FCM.getFCMToken().then(token => {
        console.log("TOKEN (getFCMToken)", token);
      });

      // This method get all notification from server side.
      FCM.getInitialNotification().then(notif => {
        console.log("INITIAL NOTIFICATION", notif);
      });

      // This method give received notifications to mobile to display.
      this.notificationUnsubscribe = FCM.on(FCMEvent.Notification, notif => {
        console.log("a", notif);
        if (notif && notif.local_notification) {
          return;
        }
        this.sendRemote(notif);
      });

      // this method call when FCM token is update(FCM token update any time so will get updated token from this method)
      this.refreshUnsubscribe = FCM.on(FCMEvent.RefreshToken, token => {
        console.log("TOKEN (refreshUnsubscribe)", token);
        this.props.onChangeToken(token);
      });
    }
  }

  //Send Notifications method
  sendRemote(notif) {
    console.log("send");
    FCM.presentLocalNotification({
      title: notif.title,
      body: notif.body,
      priority: "high",
      click_action: notif.click_action,
      show_in_foreground: true
    });
  }
  _retrieveData = async () => {
    try {
      const value = await AsyncStorage.multiGet(["id", "access_token"]);
      if (value !== null) {
        // We have data!!
        console.log(value);
        this.setState({ user_id: value[0][1] });
        this.setState({ access_token: value[1][1] });
        this.getLandingData();
      }
    } catch (error) {
      // Error retrieving data
    }
  };

  refetch = () => {
    this.setState({ refetching: true })
    this._retrieveData()
  }

  // if network state change then this method will check the isConnected true, if it is false
  // this will popup the alert --
  handleConnectionChange = isConnected => {
    this.setState({ status: isConnected });
    if (!isConnected) {
      // alert dialog starting here --
      Alert.alert(
        "Warning!",
        "Please check your network connection.",
        [
          {
            text: "Cancel",
            onPress: () => console.log("Cancel Pressed"),
            style: "cancel"
          },
          { text: "OK", onPress: () => console.log("OK Pressed") }
        ],
        { cancelable: false }
        // end here
      );
    } else {
      // this.getLandingData();
      this.refetch();
    }
  };
  // network conctivity check end here --

  handleErrors(response) {
    if (!response.ok) {
      throw Error(response.statusText);
    }
    return response;
  }

  async getLandingData() {
    // let user_id = 18;
    let url =
      Config.BASE_URL +
      `api/BIMobile/GetInitiatlTiles?userId=${encodeURIComponent(
        this.state.user_id
      )}`;
    console.log(url);

    fetch(url, {
      method: "GET",
      headers: {
        Authorization: "Bearer " + this.state.access_token
      },
    })
      .then(response => {
        return response.json();
      })

      .then(responseData => {
        //set your data here
        console.log("responseData : ", responseData.messageCode);
        if (responseData.data == null) {
          Alert.alert(
            "Oops! Something went wrong.",
            "This page did not load correctly. Please contact helpdesk.",
            [
              {
                text: "Cancel",
                isLoading: true,
                onPress: () => console.log("Cancel Pressed"),
                style: "cancel"
              },
              { text: "OK", isLoading: true, onPress: () => console.log("OK Pressed") }
            ],
            { cancelable: false }
            // end here
          );
        } else {
          if (responseData.messageCode.code == 1) {
            this.setState({ tileData: responseData.data, isLoading: false });
          } else if (responseData.messageCode.code == 0) {
            console.log(responseData.messageCode.message)
          }
        }
      })
      .catch(error => {
        console.error(error);
      });
  }

  // this function set title to the page
  module1Handler = (value, title) => {
    this.props.navigator.push({
      screen: value,
      navigatorStyle: {
        navBarHidden: false
      },
      title: title
    });
  };

  _onLayoutDidChange = e => {
    const layout = e.nativeEvent.layout;
    this.setState({ size: { width: layout.width, height: layout.height } });
  };

  render() {
    let menuItems = [];
    console.log("title Data : " + this.state.tileData);
    if (this.state.isLoading) {
      // setup progressbar to the view --
      // when the data is fetching this will spinning --
      return <ActivityIndicator style={styles.activity_indicator_view} />;
    } else {
      return (
        <View style={{ flex: 1 }} onLayout={this._onLayoutDidChange}>
          <Swiper showsButtons={false} loop={false} showsPagination={false}>
            {this.state.tileData.map((array, key) => {
              if (key == 0) {
                return (
                  <MainScreen
                    action={(value, title) => {
                      this.module1Handler(value, title);
                    }}
                    array={array}
                  />
                );
              } else {
                return (
                  <SliderScreen
                    action={(value, title) => {
                      this.module1Handler(value, title);
                    }}
                    array={array}
                  />
                );
              }
            })}
          </Swiper>
        </View>
      );
    }
  }
}
const styles = StyleSheet.create({
  activity_indicator_view: {
    flex: 1,
    flexDirection: "row",
    height: "40%",
    justifyContent: "space-around",
    padding: 10
  }
});

感谢有人可以帮助我改正方式。谢谢。

0 个答案:

没有答案