Flutter 在TV上使用webview_flutter无法使用遥控器控制滚动的问题

262 阅读2分钟

flutter实现WebView加载url及遥控器控制上下滚动

  1. 按照之前的想法,RawKeyboardListener控制焦点,在onKey中控制webview的上下滚动
class _WebviewPageState extends State<WebviewPage> {
  final WebViewController _controller = WebViewController()
    ..setJavaScriptMode(JavaScriptMode.unrestricted);
  final FocusNode _focusNode = FocusNode();

  @override
  void dispose() {
    super.dispose();
    _focusNode.dispose();
  }

  @override
  void initState() {
    super.initState();
    _controller.loadRequest(Uri.parse(url));
  }

  @override
  Widget build(BuildContext context) {
    return RawKeyboardListener(
        focusNode: _focusNode,
        onKey: (event) {
          if (event.isKeyPressed(LogicalKeyboardKey.arrowUp)) {
            var currentPosition = await _controller.getScrollPosition();
    _controller.scrollBy(currentPosition.dx.toInt(), currentPosition.dy.toInt() - 200);
          } else if (event.isKeyPressed(LogicalKeyboardKey.arrowDown)) {
            var currentPosition = await _controller.getScrollPosition();
    _controller.scrollBy(currentPosition.dx.toInt(), currentPosition.dy.toInt() + 200);
          }
        },
        child: WebViewWidget(
          controller: _controller,
        ));
  }
}
  1. 测试发现使用遥控器的上下键可以触发onKey事件,但是webview无法滚动,于是想到以下修复方法
    • 给WebView添加父结点SingleChildScrollView,通过控制SingleChildScrollView达到控制WebView的滚动,方案可行,但是需要获取到WebView加载的content的高度(无法获取到),如果预先给一定的高度是可以控制WebView的滚动,但是无法给精确的高度,故方案不完美
    • 修改scrollBy方法为scrollTo方法,方案不可行
  2. 使用手指可以滑动故可以确定确实是可以WebView确实是加载的高度比屏幕高度大,继续查找问题出现的原因
    • 查看HTML源码发现,可以滚动的并不是HTML结点,而是里面的某一个子结点,故想到了修复问题的方法,只需要使用JS注入的方式,控制可以滚动的结点即可
onKey: (event) {
          if (event.isKeyPressed(LogicalKeyboardKey.arrowUp)) {
            _controller.runJavaScript('''
  var element = 获取可滚动的结点;
  if (element) {
    element.scrollTop -= 200;
  }
''');
          } else if (event.isKeyPressed(LogicalKeyboardKey.arrowDown)) {
            _controller.runJavaScript('''
  var element = 获取可滚动的结点;
  if (element) {
    element.scrollTop += 200;
  }
''');
          }
        }

结论 其实在整个解决问题的过程中,并不是如文中所说的简单,还是经过了一些波折,比如看webview是否可以滚动,发现确实调用方法后无法滚动,于是想为什么不能滚动等等一系列问题。解决问题不易,点个赞吧