Flutter,ListView.builder onTap 奇怪的行为

Flutter, ListView.builder onTap strange behavior

在按下键 1 时,ListView 添加 1 个图块,在按键 2 时,ListView 删除一个图块,但在 ListView 或 Text() 小部件之外用鼠标单击后,键盘键停止响应,终端中不会显示任何错误。

我想,FocusNode 可能是在 ListView 外单击后被释放的,但经过测试,情况似乎并非如此

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class OnTapWidgetIssue extends StatefulWidget {
  OnTapWidgetIssue({Key? key}) : super(key: key);

  String testOnTap = '';
  int nOfList = 1;

  @override
  _OnTapWidgetIssueState createState() => _OnTapWidgetIssueState();
}

class _OnTapWidgetIssueState extends State<OnTapWidgetIssue> {
  final FocusNode _focusNode = FocusNode();
  @override
  void dispose() {
    _focusNode.dispose();
    print('_focusNode.dispose()');
    super.dispose();
  }

  void _handleKeyEvent(RawKeyEvent event) {
    if (event is RawKeyDownEvent &&
        event.data.logicalKey == LogicalKeyboardKey.digit1) {
      widget.nOfList += 1;
      setState(() {});
    }

    if (event is RawKeyDownEvent &&
        event.data.logicalKey == LogicalKeyboardKey.digit2) {
      if (widget.nOfList > 1) {
        widget.nOfList--;
        setState(() {});
      } else {}
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: MenuDrawer(),
      appBar: AppBar(title: Text('OnTap-widget.Issue')),
      body: RawKeyboardListener(
        autofocus: true,
        focusNode: _focusNode, // <-- more magic
        onKey: _handleKeyEvent,
        child: Column(children: [
          Text(widget.testOnTap, style: TextStyle(fontSize: 52.0)),
          Text('''
          press 1 to add ListTile
          press 2 to remove ListTile
          '''),
          Expanded(
            child: Row(
              children: [
                Expanded(
                  flex: 2,
                  child: SizedBox(),
                ),
                Expanded(
                  flex: 1,
                  // child: SizedBox(),
                  // // ),
                  child: ListView.builder(
                    itemCount: widget.nOfList,
                    // itemCount: widget.testOnTap.length,
                    itemBuilder: (_, i) {
                      return ListTile(
                        title: Text('$i'),
                        onTap: () {
                          widget.testOnTap = widget.testOnTap + i.toString();
                          setState(() {});
                        },
                        // Handle your onTap here.
                      );
                    },
                  ),
                ),
                Expanded(
                  flex: 2,
                  child: SizedBox(),
                ),
              ],
            ),
          ),
        ]),
      ),
    );
  }
}

我在应用程序中单击转到新页面时也遇到错误

Error: A FocusNode was used after being disposed.
Once you have called dispose() on a FocusNode, it can no longer be used.
    at Object.throw_ [as throw] (http://localhost:49535/dart_sdk.js:5061:11)
    at http://localhost:49535/packages/flutter/src/foundation/change_notifier.dart.lib.js:66:21
    at focus_manager.FocusNode.new.[_debugAssertNotDisposed] (http://localhost:49535/packages/flutter/src/foundation/change_notifier.dart.lib.js:69:25)
    at focus_manager.FocusNode.new.notifyListeners (http://localhost:49535/packages/flutter/src/foundation/change_notifier.dart.lib.js:131:41)
    at focus_manager.FocusNode.new.[_notify] (http://localhost:49535/packages/flutter/src/widgets/widget_inspector.dart.lib.js:42893:12)
    at focus_manager.FocusManager.new.[_applyFocusChange] (http://localhost:49535/packages/flutter/src/widgets/widget_inspector.dart.lib.js:43665:26)
    at Object._microtaskLoop (http://localhost:49535/dart_sdk.js:38778:13)
    at _startMicrotaskLoop (http://localhost:49535/dart_sdk.js:38784:13)
    at http://localhost:49535/dart_sdk.js:34519:9

然而,我在抽屉菜单中选择练习页面时没有出现此错误,只有从主页转到这个新页面时才会出现此错误。 Exercise 和 Home pages 有点相似,但在某些方面还是有区别的。

感谢

从技术上讲,您并不是将 onTap 添加到 ListView.builder,而是将其添加到构建器添加的每个 ListTile。 :)

声明你的两个状态变量:

String testOnTap = '';
int nOfList = 1;

_OnTapWidgetIssueState class 内,而不是 OnTapWidgetIssue class。惯例是分别将它们命名为 _testOnTap_nOfList,因为它们对 class.

是私有的

并更新 setState 调用内部的两个变量,而不是外部调用。