How to scroll flutter web app using arrow keys
Asked Answered
D

5

8

I just build and deployed a flutter web app. The problem I encountered is that it doesn't scroll when I press arrow keys, also there is no scroll bar. (Only 2 figure gesture scrolling is possible)

I'm using SingleChildScrollView() with the column as its child.

Is there a way to implement them?

Or just one of them?

Dunn answered 9/8, 2020 at 18:41 Comment(0)
W
14

The code from Karan works, but when the app is in Debug Mode, instead of using the event.logicalKey.debugName == "Arrow Up", we could use event.logicalKey == LogicalKeyboardKey.arrowUp which works in both the debug and release mode.

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(),
                ),
            ),
        );
    }
}
Webbed answered 11/8, 2020 at 11:0 Comment(1)
Why have you used the if (kReleaseMode) statement? Looks like both the conditions have the exact same statement that is executed i.e the animateTo call. Why bother using the if condition at all?Rattletrap
D
5

The Most simplest way to Scroll using mouse or Keyboard Arrow keys on Flutter Web is

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

No need to pass any ScrollController

Driveway answered 23/11, 2022 at 18:36 Comment(1)
This worked for me! Without having to add lot of controller oriented code.Londalondon
D
2

I found one solution ...

Hope this helps someone with the same issue...

Using RawKeyboardListener(), we can listen to any keyboard stroke.

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:...

    }
  }

  
Dunn answered 10/8, 2020 at 6:15 Comment(0)
T
1

You can wrap ScrollBar to SingleChildScrollView to show scroll bar, like this:

Scrollbar(
      child: SingleChildScrollView(
            child: Container(),
));
Tryptophan answered 9/8, 2020 at 20:29 Comment(1)
Yes, I did that and used ScrollController(). But I cannot click on that and drag to scroll.Dunn
S
0

For the answers that are mentioned above to work, you need the following imports:

import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
Stadtholder answered 13/10, 2020 at 17:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.