Индикатор загрузки интерактивного просмотра

Я пытаюсь показать индикатор загрузки в webweb, как показано ниже. Индикатор загрузки показывается, но после загрузки страницы отображается белый фон. Если я перейду на startInLoadingState на false, веб-контент показывается, но индикатор загрузки не отображается. Он вскакивает в "реагировать-родной": "0.46.3" на 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} />

Ответ 1

Мне нравится этот подход, который показывает индикатор активности, наложенный на загрузочный веб-просмотр, поэтому вам не нужно ждать, пока вся страница будет загружена, чтобы начать просмотр содержимого.

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

Ответ 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();
        }}
      />
    );
  }

Ответ 3

Я решил эту проблему и после некоторого исследования нашел довольно хорошее решение.

Это требует "оверлейной реакции-загрузки-вращения-наложения"

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

Я думаю, что я не пропустил ни одной строки.

Ответ 4

Измените функцию renderLoadingView следующим образом, а индикатор загрузки должен работать по желанию:

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

По существу, просто удалите animating (как это не требуется для данного использования) и hidesWhenStopped реквизита из вашего ActivityIndicator. Надеюсь, это поможет.

Ответ 5

Я использовал решение @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 View {flex: 1}, а ActivityIndicator находится в верхней части нижнего вида. Я сосредоточил это.

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

И эта строка устанавливает непрозрачность, когда у вас есть состояние загрузки, там есть два разных вида. В виде сверху есть WebView и есть черная нижняя граница View, принадлежащая WebView Для закрытия я исправил его с помощью белого вспомогательного вида.

Ответ 6

Эй, братан, это мое решение, вы должны использовать событие 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',
  },
});