flutter实现WebView加载url及遥控器控制上下滚动
- 按照之前的想法,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,
));
}
}
- 测试发现使用遥控器的上下键可以触发onKey事件,但是webview无法滚动,于是想到以下修复方法
- 给WebView添加父结点SingleChildScrollView,通过控制SingleChildScrollView达到控制WebView的滚动,方案可行,但是需要获取到WebView加载的content的高度(无法获取到),如果预先给一定的高度是可以控制WebView的滚动,但是无法给精确的高度,故方案不完美
- 修改scrollBy方法为scrollTo方法,方案不可行
- 使用手指可以滑动故可以确定确实是可以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是否可以滚动,发现确实调用方法后无法滚动,于是想为什么不能滚动等等一系列问题。解决问题不易,点个赞吧