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
调用内部的两个变量,而不是外部调用。
在按下键 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
调用内部的两个变量,而不是外部调用。