在Webview页面导航之间显示加载指示器

3
我在Webview中有一个URL,例如https://www.nytimes.com/。目前的代码可以加载初始页面,但如果我在链接中输入或点击任何东西,页面需要一段时间来加载,并且网站中没有加载指示器。是否有任何方法可以在React Native上放置页面加载指示器,特别是在单击任何链接或加载页面时,特别是如果它由服务器端呈现,例如Next.js?
以下是我的ReactNative代码。
import * as React from 'react';
import {
  View,
  Text,
  Image,
  SafeAreaView,
  ScrollView,
  TextInput,
  TouchableOpacity,
} from 'react-native';
import styles from './styles';
import { WebView } from 'react-native-webview';
// import WelcomeSwiper from '../../components/WelcomeScreen/WelcomeSwiper';

import LoadingIcon from '../../components/Loading/index.js';

const WebView = ({ navigation }) => {


  return (
    <SafeAreaView style={styles.container}>

      <WebView
        javaScriptEnabled={true}
        domStorageEnabled={true}
        renderLoading={LoadingIcon}
        source={{ uri: 'https://www.nytimes.com/ ' }}
        startInLoadingState={true}

      />
    </SafeAreaView>
  );
};

export default WebView;

这是我的加载组件

import React from 'react';
import { StyleSheet, Platform, ActivityIndicator } from 'react-native';


const LoadingIcon = () => {
    return (

        <ActivityIndicator
            color='#009688'
            size='large'
            style={styles.ActivityIndicatorStyle}
        />
    );
}

export default LoadingIcon;


const styles = StyleSheet.create(
    {

        WebViewStyle:
        {
            justifyContent: 'center',
            alignItems: 'center',
            flex: 1,
            marginTop: (Platform.OS) === 'ios' ? 20 : 0
        },

        ActivityIndicatorStyle: {
            position: 'absolute',
            left: 0,
            right: 0,
            top: 0,
            bottom: 0,
            alignItems: 'center',
            justifyContent: 'center'

        }
    });

你的代码出了问题还是你想要其他的解决方案? - Anku Singh
这段代码在页面第一次加载时可以正常工作,但是在页面加载后加载的链接无法正常工作。 - user9538877
2个回答

5
我们可以使用以下两种方法来获得结果:
  1. 您可以使用 onLoadProgress 方法检查 WebView 是否正在加载某些内容。此方法会返回介于 0 和 1 之间的数字。如果页面完全加载,它将返回数字 1,并根据其更新您的状态并显示 ActivityIndicator:

  2. 您可以使用 onLoadStartonLoadEnd 来更新您的状态,并根据其显示 ActivityIndicator!

有关更多信息,请参见:https://github.com/react-native-community/react-native-webview/blob/master/docs/Reference.md#onloadprogress

您还可以使用在 WebView 中包装过的 ActivityIndicator,*不要忘记这个方法适用于 ios,在 android 上请将其放在 WebView 外部

enter image description here

以下是您的工作代码示例:

import React, {useState} from 'react';
import {View, Text, SafeAreaView, ActivityIndicator} from 'react-native';
import {WebView} from 'react-native-webview';

function WebViewTest() {
  const [isLoading, setLoading] = useState(false);
  return (
    <SafeAreaView style={{flex: 1}}>
      <WebView
        source={{uri: 'https://www.nytimes.com/'}}
        onLoadStart={(syntheticEvent) => {
          setLoading(true);
        }}
        onLoadEnd={(syntheticEvent) => {
          setLoading(false);
        }} />
        {isLoading && (
          <View style={{flex: 10, backgroundColor: 'white'}}>
            <ActivityIndicator
              color="#009688"
              size="large"
            //   style={{position: 'absolute', left: 200, top: 300}}
            />
          </View>
        )}
    </SafeAreaView>
  );
}

export default WebViewTest;

希望能对您有所帮助。


我想WebView不能有子元素,我收到了这个错误:RNCWebViewManager无法转换为ViewGroupManager。 - user9538877
progress将返回0-1,但我已经搜索了很多,但找不到progress的文档? - weiya ou
onLoadProgress是您可以用来检查进度的属性@weiyaou - Amir Doreh
https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md#onloadprogress @weiyaou - Amir Doreh
这对我似乎没用。在同一源域内的页面点击上,LoadProgress似乎没有被调用。 - K2xL
显示剩余5条评论

3

我使用onLoadProgress来解决这个问题。

renderLoading函数仅在Webview组件的初始加载状态下调用。使用renderLoading无法帮助在任何页面链接上点击或在Webview页面之间导航时显示活动指示器。

检查onLoadStartonLoadEnd在Android中很有用,但在iOS中,onLoadEnd在后退手势中不会被调用,导致活动指示器无限旋转。

onLoadProgress在Webview处于加载状态时返回0-1之间的数字。您可以检查其进度状态并更新活动指示器状态。

有关更多有关onLoadProgress的信息,请参见:onLoadProgress

以下是一个可工作的代码示例:

import React, {useState} from 'react';
import {View, Text, SafeAreaView, ActivityIndicator} from 'react-native';
import {WebView} from 'react-native-webview';

function WebViewTest() {
  const [isLoading, setLoading] = useState(false);
  return (
    <SafeAreaView style={{flex: 1}}>
      <WebView
        source={{uri: 'https://www.nytimes.com/'}}
        onLoadProgress={({nativeEvent}) => {
                    if (nativeEvent.progress != 1 && isLoading == false ) {
                        setLoading(true)
                    } else if (nativeEvent.progress == 1 ) {
                        setLoading(false)
                    }
                }} 
        />
        {isLoading && (
          <View style={{flex: 10, backgroundColor: 'white'}}>
            <ActivityIndicator
              color="#009688"
              size="large"
            //   style={{position: 'absolute', left: 200, top: 300}}
            />
          </View>
        )}
    </SafeAreaView>
  );
}

export default WebViewTest;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接