如何使用箭头键滚动Flutter Web应用程序

8
我刚刚构建并部署了一个Flutter Web应用程序,但遇到的问题是在按箭头键时无法滚动,也没有滚动条(仅支持使用两个手指手势滚动)。我正在使用SingleChildScrollView()作为其子组件的列。请问有没有一种方法可以实现它们?或者只是其中之一?
5个回答

14

卡兰的代码是可行的,但当应用程序处于调试模式时,我们可以使用 event.logicalKey == LogicalKeyboardKey.arrowUp 代替 event.logicalKey.debugName == "Arrow Up" ,这在调试和发布模式下都可用。

class _MyKeyboardScrollingPageState extends State<MyKeyboardScrollingPage> {

    final ScrollController _controller = ScrollController();
    final FocusNode _focusNode = FocusNode();

    void _handleKeyEvent(RawKeyEvent event) {
        var offset = _controller.offset;
        if (event.logicalKey == LogicalKeyboardKey.arrowUp) {
            setState(() {
                if (kReleaseMode) {
                    _controller.animateTo(offset - 200, duration: Duration(milliseconds: 30), curve: Curves.ease);
                } else {
                    _controller.animateTo(offset - 200, duration: Duration(milliseconds: 30), curve: Curves.ease);
                }
            });
        }
        else if (event.logicalKey == LogicalKeyboardKey.arrowDown) {
            setState(() {
                if (kReleaseMode) {
                    _controller.animateTo(offset + 200, duration: Duration(milliseconds: 30), curve: Curves.ease);
                } else {
                    _controller.animateTo(offset + 200, duration: Duration(milliseconds: 30), curve: Curves.ease);
                }
            });
        }
    }


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


    @override
    Widget build(BuildContext context) {
        return Scaffold(
            body: RawKeyboardListener(
                autoFocus = true,
                focusNode = _focusNode,
                onKey: _handleKeyEvent,
                child: SingleChildScrollView(
                    controller: _controller,
                    child: SomeAwesomeWidget(),
                ),
            ),
        );
    }
}

为什么你使用了 if (kReleaseMode) 语句?看起来两个条件都执行了完全相同的语句,即 animateTo 调用。干嘛还要使用 if 条件呢? - CodeSadhu

3

在Flutter Web上使用鼠标或键盘箭头键滚动的最简单方式是

ListView(
                    primary: true,
                    scrollDirection: Axis.vertical,
                    children: 

不需要传递任何ScrollController


这对我来说很有效!而且不需要添加大量的控制器相关代码。 - hardik9850

2

我找到了一个解决方案...

希望这能帮助到遇到同样问题的人...

使用RawKeyboardListener(),我们可以监听任何键盘按键。

class _MyHomePageState extends State<MyHomePage> {
  final ScrollController _controller = ScrollController();
  final FocusNode _focusNode = FocusNode()
  
  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  void _handleKeyEvent(RawKeyEvent event) {
    var offset = _controller.offset;    //Getting current position
    if (event.logicalKey.debugName == "Arrow Down")  {
      setState(() {
        if (kReleaseMode) {
          //This block only runs when the application was compiled in release mode.
          _controller.animateTo(offset + 50,
              duration: Duration(milliseconds: 200), curve: Curves.ease);
        } else {
          // This will only print useful information in debug mode.
          // print(_controller.position); to get information..
          _controller.animateTo(offset + 50,
              duration: Duration(milliseconds: 200), curve: Curves.ease);
        }
      });
    } else if (event.logicalKey.debugName == "Arrow Up"){
      setState(() {
        if (kReleaseMode) {
          _controller.animateTo(offset - 50,
              duration: Duration(milliseconds: 200), curve: Curves.ease);
        } else {
          _controller.animateTo(offset - 50,
              duration: Duration(milliseconds: 200), curve: Curves.ease);
        }
      });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: RawKeyboardListener(
        autofocus: true,
        focusNode: _focusNode,
        onKey: _handleKeyEvent,
        child: SingleChildScrollView(
          controller: _controller,
          child:...

    }
  }

  

1
你可以将ScrollBar包裹在SingleChildScrollView中以显示滚动条,如下所示:
Scrollbar(
      child: SingleChildScrollView(
            child: Container(),
));

是的,我做了那个并使用了ScrollController()。但我无法点击并拖动以滚动。 - Karan Owalekar

0
为使上述答案有效,您需要导入以下内容:
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接