likes
comments
collection
share

Flutter webview_flutter滑动监听

作者站长头像
站长
· 阅读数 15

前言

当需要使用webview时,常用的插件有webview_flutterflutter_webview_pluginflutter_inappwebview等。

项目中已经使用的是官方的webview_flutter

问题:

总的来说webview_flutter可以满足大部分的webview相关需求,直到有一天产品小可爱说网页在顶部时,顶部标题栏背景为白色,之后网页滑动到一定距离的时候需要变成透明。我一听,so easy啊,WebViewController里有相关的方法监听:

Flutter webview_flutter滑动监听

我只需要加个Listener手势监听,在move里判断getScrollY()的距离就OK了。

Listener(
  child: WebView(initialUrl: "http://www.baidu.com"),
  onPointerMove: (PointerMoveEvent event) {
    webViewController?.getScrollY().then((value) {
      if (value > 200) {
        //标题栏背景变白色
      } else {
        ////标题栏背景变透明
      }
    });
  },
);

然而....

Flutter webview_flutter滑动监听

手势滑动是有惯性的,当快速滑动的时候,手指离开屏幕,会因为惯性继续滑动一段距离。而由于我们监听的是手势操作,当手指离开屏幕,手势监听也就从onPointerMove走到了onPointerUp,也就没办法再监听webViewController?.getScrollY(),惯性滚动的距离就没有监听到,那此时所展现的效果自然就不理想了:

快速下滑屏幕的时候,假设手指离开屏幕的时候监听到getScrollY()=500,但由于惯性网页继续滚动,直到滚回网页顶部。但由于手指离开了屏幕没有继续监听getScrollY(),getScrollY()的最后取值就是500,可此时网页已经惯性滚回到顶部了,此时标题栏依然是透明,而不是变回白色。

Flutter webview_flutter滑动监听

解决

遇到问题,咱就解决问题。 反复翻看了webview_flutter的代码,确实没有这个监听,然后联想到即便是在做Android原生开发的时候,webview也是没有提供公开的方法或设置让我们对网页的滚动进行监听的,如果要监听那就需要在原生webview的onScrollChanged增加监听。

修改FlutterWebViewClient,增加方法

void getOffsetY(int offsetY) {
    Map<String, Object> args = new HashMap<>();
    args.put("offsetY", offsetY);
    methodChannel.invokeMethod("getOffsetY", args);
}

Flutter webview_flutter滑动监听

修改FlutterWebView

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressWarnings("unchecked")
FlutterWebView(
    final Context context,
    BinaryMessenger messenger,
    int id,
    Map<String, Object> params,
    View containerView) {

  ///增加监听
  if (webView instanceof CustomWebView){
    ((CustomWebView)webView).setOnScrollChangedCallback(new CustomWebView.OnScrollChangedCallback() {
      @Override
      public void onScroll(int dx, int dy) {
        flutterWebViewClient.getOffsetY(dy);
        Log.d("onScroll",dy+"");
      }
    });
  }

Flutter webview_flutter滑动监听

platform_interface.dart里修改WebViewPlatformCallbacksHandler

增加供外部调用的getOffsetY()

void getOffsetY(int offsetY);

Flutter webview_flutter滑动监听

webview_method_channel.dart修改MethodChannelWebViewPlatform

_onMethodCall里新增getOffsetY类型

case 'getOffsetY':
  _platformCallbacksHandler.getOffsetY(call.arguments['offsetY']);
  return null;

webview_flutter.dart修改WebView

新增getOffsetY

Flutter webview_flutter滑动监听

_PlatformCallbacksHandler里新增

@override
void getOffsetY(int offsetY){
  if (_widget.getOffsetY != null) {
    _widget.getOffsetY!(offsetY);
  }
}

Flutter webview_flutter滑动监听

至此,就成功增加了webview的滑动监听

Flutter webview_flutter滑动监听