Expo Webview中如何通过下拉刷新页面?

Rai*_*ain 4 android native refresh android-webview reactjs

我用 Expo 制作了 Webview 应用程序,React-Native 观看 youtube。

起初我做了这样的基本应用程序

import * as React from 'react';
import { WebView } from 'react-native-webview';

export default class App extends React.Component {
  render() {
    return <WebView 
    source={{ uri: 'https://www.google.com' }} 
    allowsFullscreenVideo={true} 
    allowsBackForwardNavigationGestures={true}
    style={{ marginTop: 20 }} />;
  }
}
Run Code Online (Sandbox Code Playgroud)

在 Android apk 中,“返回”按钮不起作用。如果我触摸它,应用程序就会关闭。但我想回到后页。

所以我就这样改了:

import * as React from 'react';
import {Component} from 'react';
import {View,BackHandler,Platform} from 'react-native';
import {WebView} from 'react-native-webview';

export default class App extends Component {
  constructor(props) {
    super(props);
  }
  webView = {
    canGoBack: false,
    ref: null,
  }

  onAndroidBackPress = () => {
    if (this.webView.canGoBack && this.webView.ref) {
      this.webView.ref.goBack();
      return true;
    }
    return false;
  }

  UNSAFE_componentWillMount() {
    if (Platform.OS === 'android') {
      BackHandler.addEventListener('hardwareBackPress', this.onAndroidBackPress);
    }
  }

  UNSAFE_componentWillUnmount() {
    if (Platform.OS === 'android') {
      BackHandler.removeEventListener('hardwareBackPress');
    }
  }

  render() {
    return (
      <View style={{flex:1}}>
        <WebView
          ref={(webView) => { this.webView.ref = webView; }}
          onNavigationStateChange={(navState) => { this.webView.canGoBack = navState.canGoBack; }}
          automaticallyAdjustContentInsets={false}
          source={{ uri: 'https://www.google.com' }}
          allowsFullscreenVideo={true}
          javaScriptEnabled={true}
          domStorageEnabled={true}
          startInLoadingState={true}
          style={{marginTop: 25}}
        />
    </View>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

后退按钮终于起作用了。如果我触摸它,我就会移至背面。

但我意识到这个Webview应用程序无法刷新页面所以我搜索了3天。这就是我所期望的功能。在此链接中,下拉页面时可以看到圆形箭头。 https://reactnative.dev/docs/refreshcontrol?redirected

所以我混合了代码,但它不起作用

import * as React from 'react';
import {Component} from 'react';
import {WebView} from 'react-native-webview';
import {
  ScrollView,View,BackHandler,Platform,
  RefreshControl,
  StyleSheet,
  Text,
  SafeAreaView,
} from 'react-native';
import Constants from 'expo-constants';


function wait(timeout) {
  return new Promise(resolve => {
    setTimeout(resolve, timeout);
  });
}

export default class App extends Component {
    
    
  const [refreshing, setRefreshing] = React.useState(false);

  const onRefresh = React.useCallback(() => {
    setRefreshing(true);
    wait(2000).then(() => setRefreshing(false));
  }, [refreshing]);

  constructor(props) {
    super(props);
  }
  webView = {
    canGoBack: false,
    ref: null,
  }

  onAndroidBackPress = () => {
    if (this.webView.canGoBack && this.webView.ref) {
      this.webView.ref.goBack();
      return true;
    }
    return false;
  }

  UNSAFE_componentWillMount() {
    if (Platform.OS === 'android') {
      BackHandler.addEventListener('hardwareBackPress', this.onAndroidBackPress);
    }
  }

  UNSAFE_componentWillUnmount() {
    if (Platform.OS === 'android') {
      BackHandler.removeEventListener('hardwareBackPress');
    }
  }

  render() {
    return (
    <SafeAreaView style={styles.container}>
      <ScrollView
        contentContainerStyle={styles.scrollView}
        refreshControl={
          <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
        }
      >
        <WebView
          ref={(webView) => { this.webView.ref = webView; }}
          onNavigationStateChange={(navState) => { this.webView.canGoBack = navState.canGoBack; }}
          automaticallyAdjustContentInsets={false}
          source={{ uri: 'https://www.google.com' }} 
          allowsFullscreenVideo={true}
          javaScriptEnabled={true}
          domStorageEnabled={true}
          startInLoadingState={true}
          style={{marginTop: 25}}
        />
      </ScrollView>
    </SafeAreaView>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

这是错误信息..

Error: /workspace/Human_Impact/App.js: Unexpected token (23:8)

  21 |
  22 |
> 23 |   const [refreshing, setRefreshing] = React.useState(false);
     |         ^
  24 |
  25 |   const onRefresh = React.useCallback(() => {
  26 |     setRefreshing(true);
Failed building JavaScript bundle.
Run Code Online (Sandbox Code Playgroud)
  • 结论:我需要这些功能
  1. 如果我触摸 Android 硬件后退按钮一次,转到后页,在很短的时间内两次,结束应用程序。(安卓)
  2. 如果我下拉,则刷新网页。(iOS / 安卓均可)

小智 5

首先,您可以向ScrollViewWebView添加样式:

container: {
  position : 'relative',
},
ScrollStyle: {
 backgroundColor : 'white',
 position: 'relative',
}
Run Code Online (Sandbox Code Playgroud)

然后,渲染您的ScrollViewWebView

<View style={{flex: 1}}>
    <ScrollView
        style = {styles.ScrollStyle}
        contentContainerStyle={{flex: 1}}
        refreshControl={
            <RefreshControl
              refreshing={false}
              onRefresh={this.yourFunctionReload} // exl in function : this.yourWebview.reload();
            />
        }>
        <Header />  
        <WebView
          style={styles.container}
            .....
         />
    </ScrollView>
</View>
Run Code Online (Sandbox Code Playgroud)

注意:不要忘记导入 View、ScrollView、RefreshControl 和 WebView

  • 我尝试以这种方式实现它,但是我只能向下滚动,但是当我需要向后滚动时它会刷新 (2认同)

Hér*_*oso 5

正如我之前所说,我尝试以这种方式实现它,但是我只能向下滚动,但是当我需要向后滚动时它会刷新,但是我没有得到好的结果,因为 RefreshControl 始终处于启用状态,所以我做了以下操作与前面提到的解决方案一起进行调整:

const [refreshing, setRefreshing] = useState(false);
const [refresherEnabled, setEnableRefresher] = useState(true);


  //Code to get scroll position
  const handleScroll = (event) =>  {
    console.log(Number(event.nativeEvent.contentOffset.y))
    const yOffset = Number(event.nativeEvent.contentOffset.y)
    if (yOffset === 0){
      console.log('top of the page')
      setEnableRefresher(true)
    }else{
      setEnableRefresher(false)
    }
  }
    
return (
    <SafeAreaView style={genericStyles.containerWebView}>
      <StatusBar backgroundColor={genericStyles.colors.BlueBg} barStyle={'light-content'} />
      <ScrollView style={genericStyles.scrollView} 
      contentContainerStyle={{flex: 1}}
      refreshControl={
        <RefreshControl 
          refreshing={refreshing}
          enabled={refresherEnabled}
          onRefresh={()=>{webViewRef.current.reload()}}
        />
      }>
        <WebView
          source={{ uri: your url }}
          ref={webViewRef}
          originWhitelist={['*']}
          allowsInlineMediaPlayback
          javaScriptEnabled
          scalesPageToFit
          mediaPlaybackRequiresUserAction={false}
          javaScriptEnabledAndroid
          useWebkit
          startInLoadingState={true}
          cacheEnabled
          onScroll={handleScroll}
        />
      </ScrollView>
    </SafeAreaView>
  )
}
Run Code Online (Sandbox Code Playgroud)