如何返回网页视图?我在react-native中使用react-navigation包

时间:2019-03-12 13:26:15

标签: react-native react-native-android react-navigation react-native-navigation

我在react-native中安装了react-navigation 软件包

我已经实现了标签导航,其中之一是以webview格式实现的。

我的问题是,如果我按下Android上的后退物理按钮,则会从应用程序本身转到上一个选项卡,而不是从Web视图中返回。

我已经在互联网上为Webview应用了后退按钮,但是我没有这样做。

我尝试在调试时显示onNavigationStateChange日志,但是在第一次启动后加载url时,它并没有更新。这是我实现的代码:

import React from "react";
import {BackHandler} from "react-native";
import {WebView} from "react-native-webview";

class SermonScreen extends React.Component {
    constructor(props) {
        super(props);
    }
    static navigationOptions = {
        header: null
    };

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

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

    _onNavigationStateChange(navState) {
        console.log(navState);
        this.setState({
            canGoBack: navState.canGoBack
        });
    }

    handleBackButton = () => {
        console.log(this.state);
        if (this.state.canGoBack === true) {
            this.webView.goBack();
            return true;
        } else {
            return false;
        }
    };

    render() {
        return (
            <WebView
                source={{uri: 'https://m.youtube.com/channel/UCw3kP3qCCF7ZpLUNzm_Q9Xw/videos' }}
                ref={(webView) => this.webView = webView}
                onNavigationStateChange={this._onNavigationStateChange.bind(this)}
            />
        );
    }
}

export default SermonScreen;

2 个答案:

答案 0 :(得分:1)

按照官方的webview文档,您可以尝试执行以下操作:https://github.com/react-native-community/react-native-webview/blob/master/docs/Guide.md#intercepting-hash-url-changes

通常情况下,您几乎就在那儿,但是YT导航的工作方式使其无法通过 onNavigationStateChange 捕获,这就是为什么我们注入一个JS代码来拦截这些哈希更改并发布消息的原因到父组件,然后在 onMessage 处理程序中捕获它,并正确设置状态变量。将 injectedJavaScript onMessage 属性复制到您的示例中应该可以解决您的问题。

我为您准备了一个组件,该组件似乎可以满足您的要求:

 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, { Fragment } from "react";
import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  View,
  Text,
  BackHandler,
  StatusBar
} from "react-native";
import { WebView } from "react-native-webview";
import {
  Header,
  LearnMoreLinks,
  Colors,
  DebugInstructions,
  ReloadInstructions
} from "react-native/Libraries/NewAppScreen";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.startingUrl =
      "https://m.youtube.com/channel/UCw3kP3qCCF7ZpLUNzm_Q9Xw/videos";
    this.handleBackButton = this.handleBackButton.bind(this);
  }

  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.handleBackButton);
  }

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

  handleBackButton = () => {
    console.log(this.state);
    const { canGoBack } = this.state;
    if (canGoBack) {
      this.webView.goBack();
      return true;
    } else {
      return false;
    }
  };

  render() {
    return (
      <Fragment>
        <WebView
          source={{ uri: this.startingUrl }}
          style={{ marginTop: 20 }}
          ref={webView => (this.webView = webView)}
          injectedJavaScript={`
          (function() {
            function wrap(fn) {
              return function wrapper() {
                var res = fn.apply(this, arguments);
                window.ReactNativeWebView.postMessage('navigationStateChange');
                return res;
              }
            }

            history.pushState = wrap(history.pushState);
            history.replaceState = wrap(history.replaceState);
            window.addEventListener('popstate', function() {
              window.ReactNativeWebView.postMessage('navigationStateChange');
            });
          })();

          true;
        `}
          onMessage={({ nativeEvent: state }) => {
            if (state.data === "navigationStateChange") {
              // Navigation state updated, can check state.canGoBack, etc.
              this.setState({
                canGoBack: state.canGoBack
              });
            }
          }}
        />
      </Fragment>
    );
  }
}

export default App;

答案 1 :(得分:0)

上面的回答是完美的。不过,我将 canGoBack 的状态设置为 true;我收到了一个空错误,所以:

constructor(props) {
    super(props);
    this.startingUrl = "https://app.vethorcardpag.com.br/GIF/login/0/";
    this.state = {
        canGoBack : true
    }
    this.handleBackButton = this.handleBackButton.bind(this);
}
相关问题