【问题标题】:Flutter: How can I prevent default behaviour on key press?Flutter:如何防止按键时的默认行为?
【发布时间】:2023-08-18 00:37:02
【问题描述】:

我试图拦截用户按下音量按钮以执行特定操作并阻止默认行为(音量更改)。

这是我目前的代码:

RawKeyboard.instance.addListener(_keyboardListener);

void _keyboardListener(RawKeyEvent e) {
  if(e.runtimeType == RawKeyUpEvent) {
    RawKeyEventDataAndroid eA = e.data;
    if(eA.keyCode == 24) { //volume up key
      _goNextPage();
    }
    if(eA.keyCode == 25) { //volume down key
      _goPrevPage();
    }
  }
}

我将如何防止音量变化(并阻止音量滑块出现在顶部)?

类似的 Javascript 将在关键事件上调用 event.preventDefault()

这似乎是一件相当琐碎的事情,但我无法在文档中找到任何答案。

谢谢。

【问题讨论】:

  • 您找到解决方案了吗?
  • 很遗憾,没有。

标签: events dart event-handling flutter preventdefault


【解决方案1】:

我也遇到过类似的问题,想分享一下我是如何解决的。

要停止传播,我们必须从焦点节点树中FocusNodeonKey 方法返回true。为了实现这一点,我用FocusScopeFocus 小部件包装了我的应用程序主体,如下所示:

MaterialApp(
      home: Scaffold(
          body: FocusScope(
              autofocus: true,
              child: Focus(
                  autofocus: true,
                  canRequestFocus: true,
                  onKey: (data, event) {
                    if (event.isKeyPressed(LogicalKeyboardKey.audioVolumeUp)) {
                      print("Volume up");
                      return true;
                    }
                    if (event
                        .isKeyPressed(LogicalKeyboardKey.audioVolumeDown)) {
                      print("Volume down");
                      return true;
                    }
                    return false;
                  },
                  child: Text(text: "Hallochen")))))

【讨论】:

    【解决方案2】:

    感谢 Sergey 的回答,我也能够解决这个问题。就我而言,我想创建一个 ListView,具有拉动刷新 (RefreshIndicator) 功能,适用于移动设备和 Web。

    我尝试实现一个刷新指示器,当用户单击 F5 刷新网页时会出现该指示器,但我不得不阻止浏览器实际刷新页面。

    这是我的实现示例,它可以防止在用户单击 F5 时发生刷新。

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    
    class ExamplePage extends StatefulWidget {
      @override
      _ExamplePageState createState() => _ExamplePageState();
    }
    
    class _ExamplePageState extends State<ExamplePage> {
      final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
      final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = new GlobalKey<RefreshIndicatorState>();
      
      List items = [];
    
      Future<void> _pullRefresh() async {
        await Future.delayed(Duration(milliseconds: 1000));
      }
      
      @override
      Widget build(BuildContext context) {
        return FocusScope(
          autofocus: true,
          child: Focus(
            autofocus: true,
            canRequestFocus: true,
            onKey: (data, event) {
              if (event
                  .isKeyPressed(LogicalKeyboardKey.f5)) {
                _refreshIndicatorKey.currentState!.show();
                return KeyEventResult.handled;
              }
              return KeyEventResult.ignored;
            },
            child: Container(
                padding: EdgeInsets.all(15.0),
                child: RefreshIndicator(
                  key: _refreshIndicatorKey,
                  onRefresh: _pullRefresh,
                  child: AnimatedList(
                    key: listKey,
                    initialItemCount: items.length,
                    itemBuilder: (context, index, animation) {
                      return _buildItem(context, index, animation);
                    },
                  ),
                ),
            ),
          ),
        );
      }
      
        Widget _buildItem(
          BuildContext context, int index, Animation<double> animation) {
        return Text("Example");
        }
    }
    

    【讨论】:

      最近更新 更多