之前在写 React Native 时遇到了 Webview 页面无法滑动的问题,研究了一天结果以最简单的方式解决了……

环境

  • React Native 0.63.0
  • react-native-webview 10.3.2
  • react-navigation 5

这个问题仅在 Android 7(API 24,更低的 API 版本未测试)环境下出现,Android 9(API 28)没有出现问题。

现象

以嵌套导航(Drawer+Stack)实现的页面上,在最深层嵌套(主界面 Drawer 导航,下级嵌套 Stack 导航)上的 <WebView> 无法滚动。
组件代码如下:

class LodestoneLogin extends React.Component<Props> {
// ...
  render () {
    return (
      <ScrollView>
              <WebView
                  source={{uri: navigationUrl}}
                  onNavigationStateChange={this.handleWebViewNavigationStateChange}
             />
     </ScrollView>
      )
   }
}

排查

  1. 测试机是基于 Android 7 的 EMUI 5.0,因此先排查定制系统的 BUG。
    结果:模拟器发生同样问题。

  2. 测试是否是网页问题,给 WebView 直接传入 raw html
    结果:问题仍然存在

  3. 测试是否是 <ScrollView> 问题,将 <ScrollView> 替换为 <View>,另测试不以块级元素包裹的情况
    结果:问题仍然存在

  4. 测试不在 Stack 路由上是否会发生问题。
    结果:主页、及 Drawer 路由下页面没有问题,若将 Stack 路由包裹在 Drawer 路由中则问题复现。

解决方案

在测试中偶然发现,WebView 滑动时实际上会穿过该页面,对此 Stack 的父级页面进行滑动。
对照了官方 demo,对 <ScrollView> 设置 backgroundColor 后问题解决。

在 Web 开发里就算不设置 background-color,对元素的操作也不会穿透到其父级元素下,但 React Native 在低版本 Android 上不知为何表现如此。
虽然我是为了继续使用自己所掌握的技术栈才选择 React Native 而不是 Native 开发 Android App,不过以后遇到这种问题大概得先抛弃既有思维才好判断、解决问题……
不要说什么读源码,没学过 Native 读源码也读不出个所以然吧哼