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?

5 Answers 5

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(),
                ),
            ),
        );
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

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?
6

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

1 Comment

This worked for me! Without having to add lot of controller oriented code.
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:...

    }
  }

  

Comments

1

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

Scrollbar(
      child: SingleChildScrollView(
            child: Container(),
));

1 Comment

Yes, I did that and used ScrollController(). But I cannot click on that and drag to scroll.
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';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.