react-native webview 加载指示器

问题描述 投票:0回答:12

我试图在网络中显示加载指示器,如下所示。显示正在加载指示器,但页面加载后显示白色背景。如果我将 startInLoadingState 更改为 false,则会显示网页内容,但不会显示加载指示器。它发生在 ios 上的“react-native”:“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} />
react-native-ios
12个回答
65
投票

我喜欢这种方法,它显示覆盖在加载 Web 视图上的活动指示器,这样您就不必等到整个页面加载完毕才能开始查看内容。

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>
  );
}

21
投票

一个不错的方法是将属性 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();
      }}
    />
  );
}

12
投票

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

它需要“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>
        );
    }
}

我想我没有错过任何线路。


5
投票

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

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

5
投票

如果您想显示 Spinner,然后用已加载的 WebView 替换该 Spinner,这就是您的答案:


    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%'
      }
    });

4
投票

将您的

renderLoadingView
函数更改为以下内容,加载指示器应按预期工作:

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

所以本质上,只需从

animating
中删除
hidesWhenStopped
(因为给定的用法不需要)和
ActivityIndicator
道具。希望这有帮助。


4
投票

可复制和粘贴:带有加载指示器的最小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;

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}

View
,并且
ActivityIndicator
位于底部视图的顶部。我已经集中了。

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

此行设置加载状态时的不透明度,有两个不同的视图。在顶视图中有

WebView
并且有一个属于
WebView
的黑色底部边框视图。为了关闭,我用白色辅助视图修补了它。


3
投票

嘿兄弟,这是我的解决方案,你必须使用 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',
  },
});

0
投票

我的回答不会直接回答您的问题,但它会让您考虑使用骨架加载器代替传统的加载指示器(即旋转器)。我已将项目的所有指标替换为骨架,并且自更改以来收到了很好的用户反馈。

详细解释如下: https://mechanicalrock.github.io/2022/07/11/replace-circular-loaders-with-骨骼-a.html

希望这能播下种子,成为未来的模式。


0
投票

我已经使用 react-native-webview 完成了 希望对大家有帮助

import { ActivityIndicator } from 'react-native';
import { WebView } from 'react-native-webview';

export default function Browser() {
  return (
    <WebView
      source={{ uri: 'techhelpbd.com/gitdown' }}
      startInLoadingState={true}
      renderLoading={() => <ActivityIndicator
        style={{ position: 'absolute', top: 0, right: 0, bottom: 0, left: 0 }}
        size="large" color="#176FCE" />}
    />
  );
}

-1
投票

( )} />

© www.soinside.com 2019 - 2024. All rights reserved.