【问题标题】:react-native webview loading indicatorreact-native webview 加载指示器
【发布时间】:2017-07-22 16:33:41
【问题描述】:

我正在尝试在 webweb 中显示加载指示器,如下所示。正在显示加载指示器,但加载页面后显示白色背景。如果我将 startInLoadingState 更改为 false,则显示 Web 内容但不显示加载指示器。它发生在 "react-native": "0.46.3" on ios

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

【问题讨论】:

  • 如果您使用的是ActivityIndicator,请不要在其中添加prop animating。这可能是原因,您的加载指示器一直在持续......
  • renderLoadingView() { return ( ); }
  • 我没有使用道具
  • 删除此animating = {this.state.animating},它将按需要工作。

标签: react-native-ios


【解决方案1】:

我喜欢这种将活动指示器显示在正在加载的 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>
  );
}

【讨论】:

  • 很棒的解决方案!要使活动指示器真正居中(抱歉,我很挑剔),请从顶部和左侧执行- 18(大型活动指示器固定在 36x36)。
  • 迄今为止最好的解决方案!要居中加载,只需添加 style={{ position: 'absolute', left: 0, right: 0, bottom: 0, top: 0, }}
【解决方案2】:

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

【讨论】:

  • 除非我遗漏了什么,否则这只会在初始页面加载时显示加载指示器正确吗? (如果用户单击 web 视图中的链接,它不会重新显示。)
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案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%'
        }
      });
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

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

          我想我没有错过任何一行。

          【讨论】:

          【解决方案8】:

          将您的 renderLoadingView 函数更改为以下内容,加载指示器应该可以正常工作:

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

          所以本质上,只需从您的ActivityIndicator 中删除animating(因为它不是给定用法所必需的)和hidesWhenStopped 道具。希望这会有所帮助。

          【讨论】:

            【解决方案9】:

            我使用了@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>
            

            并且这一行设置了当你有加载状态时的不透明度,有两个不同的视图。在顶视图中有WebView,并且有一个黑色的底部边框视图属于WebView。为了关闭我已经用一个白色的辅助视图修补了它。

            【讨论】:

              【解决方案10】:

              ( )} />

              【讨论】:

              • 您好,欢迎来到 Stack Overflow!请拨打tour。感谢您的回答,但您是否还可以添加有关您的代码如何解决问题的解释?查看help center 获取有关如何格式化代码的信息。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-06-05
              • 1970-01-01
              • 2020-08-14
              相关资源
              最近更新 更多