react-native webview加载指示器

时间:2017-07-22 16:33:42

标签: react-native-ios

我正在尝试在webweb中显示加载指示符,如下所示。正在显示加载指示器,但页面加载后会显示白色背景。如果我将startInLoadingState更改为false,则会显示Web内容,但不会显示加载指示符。它在“反应原生”中喋喋不休:ios上的“0.46.3”

renderLoadingView() {
    return (
        <ActivityIndicator
           animating = {this.state.visible}
           color = '#bc2b78'
           size = "large"
           style = {styles.activityIndicator}
           hidesWhenStopped={true} 
        />
    );

}

<WebView
    source={source} 
    renderLoading={this.renderLoadingView} startInLoadingState={true} />

10 个答案:

答案 0 :(得分:14)

我喜欢这种方法,它显示加载Webview上覆盖的活动指示器,因此您不必等到加载整个页面才能开始看到内容。

constructor(props) {
    super(props);
    this.state = { visible: true };
  }

  hideSpinner() {
    this.setState({ visible: false });
  }

  render() {
    return (
      <View style={{ flex: 1 }}>
        <WebView
          onLoad={() => this.hideSpinner()}
          style={{ flex: 1 }}
          source={{ uri: this.props.navigation.state.params.url }}
        />
        {this.state.visible && (
          <ActivityIndicator
            style={{ position: "absolute", top: height / 2, left: width / 2 }}
            size="large"
          />
        )}
      </View>
    );
  }

答案 1 :(得分:4)

我已经解决了这个问题,经过一些研究后我找到了一个很好的解决方案。

需要"react-native-loading-spinner-overlay"

npm install --save react-native-loading-spinner-overlay

index.android.js

import Spinner from 'react-native-loading-spinner-overlay';

const main = 'http://www.myURI.pt';

class MyApp extends Component {
    constructor(props) {
        super(props);
        this.state = { uri: main, visible: true };
    }

    showSpinner() {
        console.log('Show Spinner');
        this.setState({ visible: true });
    }

    hideSpinner() {
        console.log('Hide Spinner');
        this.setState({ visible: false });
    }

    render() {
        return (
            <View>
                <Spinner
                    visible={this.state.visible}
                    textContent={'Loading...'}
                    textStyle={{ color: '#FFF' }}
                />
                <WebView
                    scalesPageToFit
                    source={{ uri: this.state.uri }}
                    onLoadStart={() => (this.showSpinner())}
                    onLoad={() => (this.hideSpinner())}
                />
            </View>
        );
    }
}

我想我并没有错过任何一条线。

答案 2 :(得分:4)

一种不错的方法是将属性 startInLoadingState 设置为 true ,并设置 renderLoading 以返回所需的视图。 请参阅下面的示例。

  displaySpinner() {
    return (
      <View>
        {/* Your spinner code goes here. 
          This one commes from react-native-material-kit library */}
        <SingleColorSpinner />
      </View>
    );
  }

  render() {
    return (
      <WebView
        startInLoadingState={true}
        source={{ uri: this.state.myUri }}
        renderLoading={() => {
          return this.displaySpinner();
        }}
      />
    );
  }

答案 3 :(得分:3)

renderLoadingView功能更改为以下内容,加载指示符应符合要求:

renderLoadingView() {
  return (
    <ActivityIndicator
      color='#bc2b78'
      size='large'
      styles={styles.activityIndicator}
    />
  );
}

基本上,只需删除animatinghidesWhenStopped(因为给定用法不需要​​)和ActivityIndicator道具selected。希望这会有所帮助。

答案 4 :(得分:3)

我使用了@ AdamG's解决方案,但是绝对路径存在问题。下面的解决方案将ActivityIndicator设置为中心,但方式不同。

<View style={{ flex: 1 }}>
            <WebView
                onLoad={() => this.hideSpinner()}
                style={{ flex: 1 }}
                source={{ uri: 'yourhtml.html' }}
            />
            <View style={{backgroundColor:'white', height:1}}></View>
            {this.state.visible && (
                <View style={{flex:1, alignItems:'center'}}>
                    <ActivityIndicator
                        size="large"
                    />
                </View>
            )}
          </View>

另外2个{flex:1} ViewActivityIndicator位于底部视图的顶部。我已经把它居中了。

  <View style={{backgroundColor:'white', height:1}}></View>

这行设置了不透明度,当您处于加载状态时,有两个不同的View。在顶视图中有WebView,底部有黑色的边框视图,属于WebView。为了结束,我用白色辅助视图对其进行了修补。

答案 5 :(得分:2)

react-native webview现在已弃用。
您可以导入react-native-webview并执行以下操作:

    <WebView
    source={{ uri: 'https://reactnative.dev' }}
    startInLoadingState={true}
    renderLoading={() => <Loading />}
    />

答案 6 :(得分:1)

嘿,这是我的解决方案,您必须使用事件onLoadEnd代替onLoad,事件onLoad对我不起作用。

import React, { Component } from 'react';
import { StyleSheet, ActivityIndicator, View } from 'react-native';
import { WebView } from "react-native-webview";

export default class MainActivity extends Component {
  constructor(props) {
    super(props);
    this.state = { visible: true };
  }

  showSpinner() {
    console.log('Show Spinner');
    this.setState({ visible: true });
  }

  hideSpinner() {
    console.log('Hide Spinner');
    this.setState({ visible: false });
  }

  render() {
    return (
      <View
        style={this.state.visible === true ? styles.stylOld : styles.styleNew}>
        {this.state.visible ? (
          <ActivityIndicator
            color="#009688"
            size="large"
            style={styles.ActivityIndicatorStyle}
          />
        ) : null}

        <WebView
          style={styles.WebViewStyle}
          //Loading URL
          source={{ uri: 'https://aboutreact.com' }}
          //Enable Javascript support
          javaScriptEnabled={true}
          //For the Cache
          domStorageEnabled={true}
          //View to show while loading the webpage
          //Want to show the view or not
          //startInLoadingState={true}
          onLoadStart={() => this.showSpinner()}
          onLoad={() => this.hideSpinner()}
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  stylOld: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  styleNew: {
    flex: 1,
  },
  WebViewStyle: {
    justifyContent: 'center',
    alignItems: 'center',
    flex: 1,
    marginTop: 40,
  },
  ActivityIndicatorStyle: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    position: 'absolute',
  },
});

答案 7 :(得分:1)

复制并粘贴:带有加载指示器的最小Webview组件

import React, { Component } from "react";
import { ActivityIndicator} from "react-native";
import { WebView } from "react-native-webview";


// Pass a "uri" prop as the webpage to be rendered
class WebViewScreen extends Component {
  constructor(props) {
    super(props);
    this.state = { visible: true };
  }
  hideSpinner() {
    this.setState({ visible: false });
  }
  render() {
    return (
      <React.Fragment>
        <WebView
          onLoadStart={() => this.setState({ visible: true })}
          onLoadEnd={() => this.setState({ visible: false })}

          // Pass uri in while navigating with react-navigation. To reach this screen use:
          // this.props.navigation.navigate("WebViewScreen", {uri: "google.ca"});
          source={{ uri: this.props.navigation.state.params.uri }} 
        />
        {this.state.visible ? (
          <ActivityIndicator
            style={{
              position: "absolute",
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              jusityContent: "space-around",
              flexWrap: "wrap",
              alignContent: "center",
            }}
            size="large"
          />
        ) : null}
      </React.Fragment>
    );
  }
}
export default WebViewScreen;

答案 8 :(得分:0)

如果要显示微调框,然后用已经加载的WebView替换该微调框,这就是您的答案:

import React from 'react';
import { StyleSheet, ActivityIndicator, View } from 'react-native';
import { WebView } from "react-native-webview";

function MyApp() {
const Spinner = () => (
    <View style={styles.activityContainer}>
      <ActivityIndicator size="large" color={white} />
    </View>
);

return (
<WebView
        bounces={false}
        startInLoadingState={true}
        renderLoading={Spinner}
        style={styles.container}
        source={{ uri: yourURL }}
        showsHorizontalScrollIndicator={false}
        scalesPageToFit
      />
)
}


export default StyleSheet.create({
  container: {
    flex: 1
  },
  activityContainer: {
    alignItems: 'center',
    justifyContent: 'center',
    position: 'absolute',
    top: 0,
    left: 0,
    backgroundColor: black,
    height: '100%',
    width: '100%'
  }
});

答案 9 :(得分:-1)

<网页视图 风格={{ 弹性:1 }} startInLoadingState={true} source={{ uri: "https://google.com" }} renderLoading={() => ( )} />